Hintergrund: Verbesserungen im MySQL-Optimizer

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.

In Pocket speichern vorlesen Druckansicht 2 Kommentare lesen
Lesezeit: 3 Min.
Von
  • Christian Kirsch

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:

  • Subqueries,
  • Abfragen mit durch LIMIT begrenzten sortierten Ergebnismengen,
  • Auswertung von WHERE-Bedingungen in der Storage Engine,
  • Multi-Range Reads und Batched Key Access,
  • Verzögerte Materialisierung abgeleiteter Tabellen,
  • IN()-Aufrufe mit einer großen Anzahl von Werten
  • und dauerhafte Statistiken.
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 und Subquery-Materialization. Dadurch ist laut Oracle die Abfrage 18 im Datenbank-Benchmark DBT3 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) 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 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, 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)