zurück zum Artikel

Hintergrund: Verbesserungen im MySQL-Optimizer

Christian Kirsch

In MySQL 5.6 haben die Entwickler sich unter anderem auf die Verbesserung des Query-Optimizers konzentriert. Dadurch sollen vor allem hÀufig benutzte Abfragen schneller laufen.

Im demnĂ€chst erscheinenden MySQL 5.6 hat Oracle den Query-Optimizer grĂŒndlich ĂŒberarbeitet, sodass der Server etliche Abfragetypen deutlich schneller als bislang ausfĂŒhrt. Betroffen sind unter anderem:

EXPLAIN INSERT UPDATE DELETE

Subqueries in Verbindung mit IN() wie die folgende

select t from film where film id
in (select film_id from film_actor
group by film_id having count(*) > 12)

seien in bisherigen MySQL-Versionen de facto nicht benutzbar gewesen, hieß es bei der Vorstellung des Release-Kandidaten von 5.6. Der Optimizer verwendet nun Semi-Joins [1] und Subquery-Materialization. Dadurch ist laut Oracle die Abfrage 18 im Datenbank-Benchmark DBT3 [2] fĂŒr MySQL ĂŒberhaupt ausfĂŒhrbar geworden – bisher habe die geschĂ€tzte AusfĂŒhrungszeit bei rund 45 Tagen gelegen, jetzt sei der Test in Sekunden beendet.

In Web-Anwendungen hĂ€ufig verwendete Abfragen mit einer sortierten Ergebnismenge, von der per LIMIT-Klausel immer nur ein kleiner Teil ausgegeben wird, hat Oracle dadurch beschleunigt, dass keine sortierten Zwischentabellen mehr erzeugt werden. Stattdessen hĂ€lt der Server nur einen Puffer fĂŒr die laut LIMIT nötigen Ergebnisse vor, den er laufend sortiert.

Mit Index Condition Pushdown (ICP [3]) bezeichnen die Entwickler das Verfahren, alle Teile einer WHERE-Bedingung anhand von Indizes auszuwerten. Tabellenzeilen, fĂŒr die sie nicht gilt, werden anders als bisher gar nicht erst gelesen. Diese Optimierung spart vor allem Platten-I/O

Die Verfahren Multi-Range Read und Batched Key Access stehen nur fĂŒr InnoDB-Tabellen zur VerfĂŒgung. Sie nutzen aus, dass bei jenen die DatensĂ€tze auf der Platte nach dem PrimĂ€rschlĂŒssel sortiert sind. Dadurch lassen sich die die Lesezugriffe reduzieren, indem sie anhand des Index die DatensĂ€tze in der Reihenfolge der PrimĂ€rschlĂŒssel stattfinden. Oracle zufolge mĂŒsse so jeder Datenblock nur einmal gelesen werden. Beim Batched Key Access, der fĂŒr Joins benutzt wird, hĂ€ngt der Performance-Gewinn allerdings stark von der GrĂ¶ĂŸe des Join-Buffers ab.

Eine weitere Optimierung betrifft Subqueries [4] im FROM-Teil eines SELECT-Statements, sogenannte Derived Tables. In MySQL 5.6 stellt der Optimizer sicher, dass diese Tabellen nur erzeugt werden, wenn das nötig ist. Insbesondere in einem EXPLAIN ist das ĂŒberflĂŒssig, ebenso wie in dem Fall, dass die Subquery ein leeres Ergebnis liefert. Falls die Tabelle erzeugt werden muss, erstellt der Server bei bestimmten Queries auch einen Index fĂŒr sie, was JOIN-Operationen beschleunigt.

Bei IN()-Klauseln mit einer großen Anzahl von Werten dauerte es laut Oracle in bisherigen Versionen von MySQL hĂ€ufig lĂ€nger, den Query-Plan aufzustellen als die Abfrage auszufĂŒhren. Das soll sich nun dadurch Ă€ndern [5], dass der Optimizer nicht mehr versucht, die genaue Zahl der möglichen Zeilen zu ermitteln, sondern sich auf Index-Statistiken verlĂ€sst.

Solche Statistiken erzeugt MySQL 5.6 jetzt genauer als bislang. Außerdem sind sie stabil, was wiederum zu stabilen AusfĂŒhrungsplĂ€nen fĂŒhrt. Der Server berechnet die Statistiken automatisch neu, wenn sich grĂ¶ĂŸere Teil der betroffenen Tabellen geĂ€ndert haben. Alternativ lassen sie sich auch manuell erstellen. (ck [6])


URL dieses Artikels:
https://www.heise.de/-1720487

Links in diesem Artikel:
[1] http://de.wikibooks.org/wiki/Relationenalgebra_und_SQL%3A_Semi-Join
[2] http://sourceforge.net/apps/mediawiki/osdldbt/index.php?title=Main_Page
[3] http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html
[4] http://dev.mysql.com/doc/refman/5.6/en/from-clause-subquery-optimization.html
[5] http://dev.mysql.com/doc/refman/5.6/en/equality-range-optimization.html
[6] mailto:ck@ix.de