SELECT * ist am Schnellsten

2005-09-17 16:26

MySQLAuf der MySQL-de Mailingliste führten wir eine Randbetrachtung, ob ein SELECT * FROM $table; schneller ist, als alle Felder, die durch das Sternchen referenziert werden, aufzulisten. Bereits ein erster Test mit dem mysql-client brachte das erstaunliche Ergebnis, dass MySQL das SELECT * tatsächlich schneller bearbeitet, als eine Auflistung aller Spalten.

Daher habe ich heute Nacht ein C-Progrämmchen geschrieben, das nichts anderes macht, als die Datenbank zu initialisieren, konnektieren, selektieren, danach das SQL-Statement auszuführen und das Ergebnis in einer Programm-Variable zu speichern. Danach habe ich noch die Anzahl rows ermitteln lassen und wieder disconnected. Die Zeit wurde in CPU-clocks gemessen (man 3 clock), und zwar nur die Zeit zwischen Absetzen des Queries zzgl. Abspeichern in der Variable.

Das ganze habe ich dann auf meiner Datenbankmaschine (1GB RAM, Sponsoren sind immer herzlich willkommen – siehe tobus.org) ausgeführt, um Plattenzugriffe zu minimieren, weil hier die 1,2 Millionen Datensätze umfassende Tabelle (inkl. der für diesen Versuch nicht notwendigen Indizies) komplett in den Arbeitsspeicher passten. die Messreihe umfasste ein elfmaliges Ausführen der SQL-Queries in sowohl unterschiedlicher Reihenfolge als auch hintereinander. Eine auffällige Auswirkung des cachings des mysqld war jedoch nicht festzustellen und auch nicht zu erwarten, da es sich ja um ein rein sequentiellen query handelt, der ohne WHERE oder ORDER Statements auskam.

Es gab also drei verschiedene Statements, zum einen das SELECT * (*), als zweites ein SELECT 'alle Felder in Datenbankreihenfolge' (r) und zu guter Letzt ein SELECT 'alle Felder in Nicht-Datenbankreihenfolge' (n).

Bei Wertung der Gesamtzeit als 100% ergab sich folgendes Bild:
select * – 95,7%
select r – 100,6%
select n – 103,6%

Bei Bezugnahme auf das Statement mit Auflistung aller Felder in der Reihenfolge, in der sie in der Tabellenstruktur angelegt wurden, ergibt sich, dass ein SELECT * um fünf Prozent schneller ist (95,2%).

Nun will ich aber diese Performancemessung etwas relativieren. Gemessen wurde, als immer nur ein (dieser) Request vom mysqld zu bewältigen war. In Hochlastumgebungen, die z.B. 10000 Requests gleichzeitg bearbeiten müssen (Hmm, kann man MySQL soweit skalieren? Ich würde da eher auf einen Cluster ausweichen als eine Datenbankmaschine mit Hardware und OS soweit aufzurüsten, dass sie das verkraftet – das schafft auch Redundanz, verursacht natürlich höhere Wartungskosten), kann es zu Engpässen an ganz anderen Stellen kommen.

Don’t use ’select *‘! Auch wenn es hier tatsächlich etwas schneller war. Ich bin auch sehr dafür, dass die MySQL-Entwickler zukünftig bei einem SELECT * eine bewußte Verzögerung einbauen, damit es langsamer wird ;)

Achja, der getestete mysqld ist 4.0.24.

Leave a Reply