<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christoph Bünte &nbsp;&raquo; Software Entwicklung Berlin</title>
	<atom:link href="http://www.christophbuente.de/kategorie/datenbanken/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.christophbuente.de</link>
	<description>Software Entwicklung</description>
	<lastBuildDate>Tue, 07 Dec 2010 11:30:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Gepatchte MySQL Version &#8211; nützliche Features schlüsselfertig eingebaut</title>
		<link>http://www.christophbuente.de/2008-07-30-gepatchte-mysql-version-nuetzliche-features-schluesselfertig-eingebaut/</link>
		<comments>http://www.christophbuente.de/2008-07-30-gepatchte-mysql-version-nuetzliche-features-schluesselfertig-eingebaut/#comments</comments>
		<pubDate>Tue, 29 Jul 2008 22:24:02 +0000</pubDate>
		<dc:creator>Christoph Bünte</dc:creator>
				<category><![CDATA[Datenbanken]]></category>
		<category><![CDATA[binaries]]></category>
		<category><![CDATA[execution plan]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[innodb statistik]]></category>
		<category><![CDATA[microslow]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[patches]]></category>
		<category><![CDATA[percona]]></category>
		<category><![CDATA[rpms]]></category>

		<guid isPermaLink="false">http://www.christophbuente.de/?p=138</guid>
		<description><![CDATA[Aufgrund mangelnder Aktivität bei der Entwicklung des aktuellen MySQL 5.0.x Zweiges der Community Version haben die Jungs von MySQL Performance Blog eine gepatchte Version der MySQL Binaries für Debian zum Download zur Verfügung gestellt. Es sind ausserdem generische X86_64 RPMs verfügbar. Neben selbst entwickelten Patches sind auch einige Verbesserungen von Drittanbietern unter anderem auch von [...]]]></description>
			<content:encoded><![CDATA[<p>Aufgrund mangelnder Aktivität bei der Entwicklung des aktuellen MySQL 5.0.x Zweiges der Community Version haben die Jungs von <a href="http://www.mysqlperformanceblog.com">MySQL Performance Blog</a> eine gepatchte Version der <a href="http://mysql.com/">MySQL</a> Binaries für <a href="http://www.debian.org/">Debian</a> zum Download zur Verfügung gestellt. Es sind ausserdem generische X86_64 <acronym title="Redhat Package Manager">RPM</acronym>s verfügbar. Neben selbst entwickelten Patches sind auch einige Verbesserungen von Drittanbietern unter anderem auch von <a href="http://www.percona.com/">Percona</a> und <a href="http://google.de">Google</a> integriert. Die Verbesserungen sind vor allem folgende:</p>
<ul>
<li>microslow, ermöglicht die Anzeige der Querydauer in Millisekunden im slowlog</li>
<li>execution plan, zeigt informationen über den Ausführungsplan im slowlog</li>
<li>InnoDB statistics, zeigt erweiterte InnoDB Auswertungen während der Query Ausführung im slowlog</li>
<li>Google patch mit Benutzerstatistik und Statistiken über Tabellen- und Indexnutzung</li>
</ul>
<p>Mehr Informationen gibt es im entsprechende <a href="http://www.mysqlperformanceblog.com/2008/07/16/mysql-releases-with-percona-patches/">Mysql Performance Blog &#8211; Percona Patches</a>.</p>
<div id="crp_related"><h3>Ähnliche Beiträge:</h3><ul><li><a href="http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/" rel="bookmark" class="crp_title">MySQL MyISAM &#8211; Index oder nicht?</a></li><li><a href="http://www.christophbuente.de/2007-11-25-ruby-on-rails-auf-mac-os-x-5-minuten-kurzanleitung/" rel="bookmark" class="crp_title">Ruby on Rails auf Mac OS X &#8211; 5 Minuten Kurzanleitung</a></li><li><a href="http://www.christophbuente.de/2008-08-19-lastfm-fur-das-iphone-gute-musik-fur-unterwegs/" rel="bookmark" class="crp_title">last.fm für das iPhone &#8211; gute Musik für unterwegs</a></li><li><a href="http://www.christophbuente.de/2007-06-04-hello-world/" rel="bookmark" class="crp_title">Herzlich Willkommen!</a></li><li><a href="http://www.christophbuente.de/2007-12-06-voiceglue-installation-interactive-voice-response-leicht-gemacht/" rel="bookmark" class="crp_title">VoiceGlue Installation &#8211; Interactive Voice Response leicht gemacht</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://www.christophbuente.de/2008-07-30-gepatchte-mysql-version-nuetzliche-features-schluesselfertig-eingebaut/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL MyISAM &#8211; Index oder nicht?</title>
		<link>http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/</link>
		<comments>http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 22:34:44 +0000</pubDate>
		<dc:creator>Christoph Bünte</dc:creator>
				<category><![CDATA[Datenbanken]]></category>
		<category><![CDATA[analyze table]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[explain]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[incorrect index]]></category>
		<category><![CDATA[Index]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[no index]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[query]]></category>
		<category><![CDATA[select]]></category>
		<category><![CDATA[solution]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/</guid>
		<description><![CDATA[Für einen Kunden habe ich mich in letzter Zeit etwas eingehender mit dem Datenbank Backend befasst. Ein Setup mit mehreren Servern, Synchronisierung und Lastverteilung existierte bereits. Jedoch konnte ich den Logfiles entnehmen, dass es hin und wieder Anfragen an den Datenbankserver gibt, die extrem lange Dauern und dadurch andere Anfragen durch Sperren behindern. Bei der [...]]]></description>
			<content:encoded><![CDATA[<p>Für einen Kunden habe ich mich in letzter Zeit etwas eingehender mit dem Datenbank Backend befasst. Ein Setup mit mehreren Servern, Synchronisierung und Lastverteilung existierte bereits. Jedoch konnte ich den Logfiles entnehmen, dass es hin und wieder Anfragen an den Datenbankserver gibt, die extrem lange Dauern und dadurch andere Anfragen durch Sperren behindern. Bei der Analyse bin ich auf ein paar interessante Details gestoßen.</p>
<p><span id="more-41"></span></p>
<p>Der Kunde hat für das Staging seiner Webanwendung zwei unterschiedliche Server. Sowohl Hardware als auch Betriebsystem sind identisch eingerichtet. Die Konfigurationsdatei für die Datenbanken sind ebenfalls gleich. Der Unterschied ist jedoch, dass auf einem System ein und die selbe Anfrage 1 Sekunde benötigt. Auf dem anderen System wartet man bis zu 5000 Sekunden. Ein <code>EXPLAIN</code> mit dem MySQL Client brachte nur die Gewissheit: Der existierende Index wird auf dem einen System nicht verwendet.</p>
<pre lang="text">mysql&gt; EXPLAIN (eine SELECT Anfrage)
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+
| table | type   | possible_keys | key     | key_len | ref            | rows   | Extra                           |
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+
| p     | ALL    | idx_on_column | NULL    |    NULL | NULL           | 3588047| Using temporary; Using filesort |
+-------+--------+---------------+---------+---------+----------------+--------+---------------------------------+</pre>
<p>Erst stand der Verdacht im Raum, dass der Index auf dem einen System nicht in den Arbeitsspeicher passt, und aus diesem Grund nicht verwendet wird. Doch ausreichend Arbeitsspeicher stand zur Verfügung. Dann erinnerte ich mich vage, dass ich mal etwas in der MySQL Dokumentation zum Thema Index gelesen hatte. Die <a href="http://dev.mysql.com/doc/refman/5.0/en/show-index.html">Kardinalität eines Index</a> sollte nach dem Anlegen mit Hilfe von <code>ANALYZE TABLE</code> bzw. <code>mysqlcheck</code> neu berechnet werden.</p>
<pre lang="bash">mysqlcheck -u USER -p PASSWORD --analyze DB_NAME [TABLE_NAME]</pre>
<p>Und tatsächlich wurde ab diesem Moment der entsprechende Index für die Anfrage verwendet. Mit Hilfe der Kardinalität kann MySQL entscheiden, ob ein Index für eine Anfrage verwendet werden kann, oder nicht. Bei fehlerhafter Kardinalität kann es vorkommen, dass die Entscheidung über das für und wider eines Index falsch getroffen werden.</p>
<p>Diese Art der Nachhilfe braucht MySQL allerdings nur beim Tabellentyp MyISAM. Der neuere Typ InnoDB ist deutlich besser in der Lage auszuwerten, ob und welche Indizes für eine bestimmte Anfrage benutzt werden können.</p>
<div id="crp_related"><h3>Ähnliche Beiträge:</h3><ul><li><a href="http://www.christophbuente.de/2007-11-25-ruby-on-rails-auf-mac-os-x-5-minuten-kurzanleitung/" rel="bookmark" class="crp_title">Ruby on Rails auf Mac OS X &#8211; 5 Minuten Kurzanleitung</a></li><li><a href="http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/" rel="bookmark" class="crp_title">Objekte und Beziehungen</a></li><li><a href="http://www.christophbuente.de/2008-07-30-gepatchte-mysql-version-nuetzliche-features-schluesselfertig-eingebaut/" rel="bookmark" class="crp_title">Gepatchte MySQL Version &#8211; nützliche Features schlüsselfertig eingebaut</a></li><li><a href="http://www.christophbuente.de/2007-12-21-voiceglue-konfiguration-server-fur-sprachanwendungen-einrichten/" rel="bookmark" class="crp_title">VoiceGlue Konfiguration &#8211; Server für Sprachanwendungen einrichten</a></li><li><a href="http://www.christophbuente.de/2008-01-24-stripes-framework-tests-fur-actionbeans-im-wizard-modus/" rel="bookmark" class="crp_title">Stripes Framework &#8211; Tests für ActionBeans im Wizard Modus</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Objekte und Beziehungen</title>
		<link>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/</link>
		<comments>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/#comments</comments>
		<pubDate>Sun, 05 Aug 2007 10:05:20 +0000</pubDate>
		<dc:creator>Christoph Bünte</dc:creator>
				<category><![CDATA[Datenbanken]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[anzahl der kinder]]></category>
		<category><![CDATA[counter_cache]]></category>
		<category><![CDATA[parent id]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.christophbuente.de/2007/08/05/objekte-und-beziehungen/</guid>
		<description><![CDATA[Wie im täglichen Leben stehen auch bei der programmatischen Nachbildung der Wirklichkeit Objekte oft in einer bestimmten Beziehung zu einander. Dabei unterscheidet man zwischen 1:1, 1:n und m:n Beziehungen. Neulich wollte ich in einer kleinen Rails Web-Applikation (siehe aktuelle Literatur) eine Ansicht einer 1:n Beziehung zweier Objekte in Listenform erstellen. Die Anforderung war allerdings, die [...]]]></description>
			<content:encoded><![CDATA[<p>Wie im täglichen Leben stehen auch bei der programmatischen Nachbildung der Wirklichkeit Objekte oft in einer bestimmten Beziehung zu einander. Dabei unterscheidet man zwischen 1:1,  1:n und m:n Beziehungen.</p>
<p>Neulich wollte ich in einer kleinen Rails Web-Applikation (siehe aktuelle Literatur) eine Ansicht einer 1:n Beziehung zweier Objekte in Listenform erstellen. Die Anforderung war allerdings, die Liste nach der Anzahl der Kinder zu sortieren und dabei die Objekte zuerst anzuzeigen, die keine Kinder haben.</p>
<p><span id="more-11"></span></p>
<p>[ad#vert-banner]</p>
<p>Damit die Ergebnismenge des SELECT Statements auch die Eltern Objekte enthält, die keine Kinder besitzen, muss ein LEFT JOIN verwendet werden. Grundsätzlich ist das zwar etwas mehr Aufwand für die Datenbank, aber dennoch schaffbar, ohne eine Ewigkeit warten zu müssen. Mit Hilfe von Indizierungen lässt sich die ganze Sache auch hinreichend beschleunigen. Das folgende SQL Statement erfüllt diese erste Anforderung:</p>
<pre lang="sql">
SELECT p.name, c.name
FROM parents AS p
LEFT JOIN children AS c
ON p.id=c.parent_id</pre>
<p>Allerdings fehlt hier die Sortierung. Das zweite Problem ist, dass das Feld <code>c.name</code> für alle kinderlosen Eltern NULL ist, und somit nicht gezählt werden kann. Folgendes Statement behebt zwar das Problem, aber die Ausführung braucht bei großen Tabellen Jahre.</p>
<pre lang="sql">
SELECT IF(c.id IS NULL,0,COUNT(*)) AS kids, p.name
FROM parents AS p
LEFT JOIN children AS c ON p.id=c.parent_id
ORDER BY kids
GROUP BY p.id</pre>
<p>Die lange Ausführungsdauer hat vor allem einen Grund: Die Sortierung geschieht auf einer Spalte, die effektiv nicht existiert, sondern erst zur Laufzeit mit Hilfe der Count Funktion erzeugt wird. Das heißt es muss erst ein kompletter Join über beide Tabellen durchgeführt werden, ehe eine Sortierung stattfinden kann. Auch eine Limitierung der Ergebnisliste mit Hilfe von LIMIT ändert daran nichts, denn die würde erst nach der Sortierung durchgeführt.</p>
<p>Um diese lange Wartezeiten zu vermeiden, habe ich mir folgendes überlegt: Man baut in die Tabelle der Elternklasse eine Spalte ein, die die Anzahl der Kinder speichert. Nun muss &#8220;nur noch&#8221; beim hinzufügen und löschen eines Kindes diese Spalte gepflegt werden. Das heißt, meine Applikation ist für die Datenintegrität zuständig.</p>
<p>Zurück zu Rails, denn da ist dieses Funktionalität bereits an Board. Getreu dem Motto &#8220;Konvention über Konfiguration&#8221;, erzeugt man lediglich die Spalte in der Tabelle der Elternklasse. Diese trägt den sprechenden Namen &lt;kindertabelle&gt;_count also in diesem falls children_count. In der Kinderklasse wird nun noch deklariert, dass der Zähler automatisch aktualisiert wird.</p>
<pre lang="ruby">
class Child < ActiveRecord::Base
  belongs_to :parent, :counter_cache => true
end</pre>
<p>Und siehe da, nun lässt sich eine normaler Finder verwenden, um den View aufzubauen. Komplett ohne JOIN!</p>
<pre lang="ruby">@parents = Parent.find(
  :all,
  :limit => 20,
  <img src='http://www.christophbuente.de/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> ffset => @parent_pages.current.to_sql[1],
  <img src='http://www.christophbuente.de/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder => "children_count ASC, parent ASC")</pre>
<p>Da jetzt nur noch real existierende Spalten für die Sortierung verwendet werden und eine effektive Limitierung der Ergebnismenge möglich ist, dauert die Anfrage nur noch wenige ms.</p>
<p>Thx Rails!</p>
<div id="crp_related"><h3>Ähnliche Beiträge:</h3><ul><li><a href="http://www.christophbuente.de/2007-10-05-frei-nehmen-um-zu-lernen/" rel="bookmark" class="crp_title">Rails tutorial &#8211;  Eine Woche lang Agile Webentwicklung</a></li><li><a href="http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/" rel="bookmark" class="crp_title">MySQL MyISAM &#8211; Index oder nicht?</a></li><li><a href="http://www.christophbuente.de/2007-06-19-performance-tests/" rel="bookmark" class="crp_title">Performance Tests</a></li><li><a href="http://www.christophbuente.de/2007-11-24-advancing-rails-ein-workshop-mit-david-a-black/" rel="bookmark" class="crp_title">Advancing Rails &#8211; Ein Workshop mit David A. Black</a></li><li><a href="http://www.christophbuente.de/2008-01-24-stripes-framework-tests-fur-actionbeans-im-wizard-modus/" rel="bookmark" class="crp_title">Stripes Framework &#8211; Tests für ActionBeans im Wizard Modus</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached (Feed is rejected)
Page Caching using memcached
Database Caching 10/30 queries in 0.033 seconds using memcached
Object Caching 909/960 objects using memcached

Served from: www.christophbuente.de @ 2012-02-08 10:05:25 -->
