26. November 2007

MySQL: UNION ALL deutlich schneller als UNION

Hierbei nimmt der Zeitgewinn mit wachsender Größe des Ergebnis-Sets zu.

Der Grund ist, dass ein

SELECT UNION

tatsächlich einem

SELECT UNION DISTINCT

entspricht. Dies bedeutet, dass MySQL sicherstellt, dass jede Ergebniszeile nur einmal in der Ergebnismenge vorhanden ist. Für diese Überprüfung wird in einer temporären Ergebnistabelle ein Key erstellt, der den Hash-Wert der jweiligen Ergebniszeile darstellt. Es wird dann dafür gesorgt, dass diese Hash-Werte unique sind. Die Berechnung der Hash-Werte kostet natürlich entsprechend Rechenzeit.

Demnach ist es performanter explizit ein

UNION ALL

auszuführen, wenn man nicht auf die Einzigartigkeit der Datensätze im Ergebnis angewiesen ist, oder auf Grund der Datenstruktur so oder so keine Ergebniszeilen doppelt vorkommen können.

MySQL: UNION SELECT schneller als OR Bedingung

SELECT column FROM table WHER a=1 OR b=2

Schneller:

SELECT column FROM table WHERE a=1

UNION

SELECT column FROM table WHERE b=2

Hintergrund: Bei Oder-Bedingungen im WHERE -Teil des Statements nutzt MySQL keine Keys, sondern führt einen Full-Table-Scan aus. Hingegen können die Keys beim UNION SELECT benutzt werden und MySQL muss im günstigsten Fall nicht in die eigentlichen Daten schauen, um die zutreffenden Datenätze zurückzuliefern.

14. Oktober 2007

InnoDB „Multi-Tablespaces“

Ein Grund, warum ich bisher InnoDB skeptisch gegenüberstand, war neben der drei bis fünfach höheren Datenmenge von InnoDB-Tabellen gegenüber myIsam-Tabellen, das “Problem”, dass bei InnoDB alle Tabellen einer Datenbank in einer einzigen Datei abgelegt werden.

Dies macht es sehr schwer, mal eben eine einzelne Tabelle zu Backuppen oder im laufenden Betrieb wieder herzustellen. Muss man ein Backup einspielen, so müssen entsprechend alle Zugriffe auf die Tabellen der Datenbank unterbrochen werden und die entsprechenden Anwendungen heruntergefahren werden, was unter Umständen nich praktikabel ist.

Wie ich aber dem Dem offiziellen MySQL 5-Handbuch entnehmen konnte, gibt es durchaus die Möglichkeit unter InnoDB, ähnlich, wie bei myIsam tabellenbasierte Dateien zu benutzen. Das ganze wird dann Multi-Tablespaces genannt und ist recht einfach zu konfigurieren.

Man muss lediglich in der

my.cnf

im Abschnitt

[mysqld]

folgende Zeile einfügen:

bbinnodb_file_per_table

Nach dem Neustart des MySQL-Servers wird für jede neu angelegte Tabelle eine Datei nach dem Schema

tbl_name.ibd

angelegt.

Dies ähnelt dem Verhalten von MyIsam, mit dem Unterschied, dass bei InnoDB sowohl die eigentlichen Daten, als auch die Indizes in diese eine Datei geschrieben werden, wohingegen MyIsam hierfür jeweils eine eigene Datei anlegt.

Die

tbl_name.frm

wird analog bei beiden Storage Engines angelegt.

Bereits bestehende Tabellen verbleiben jedoch nach dem Neustart in der bisherigen Struktur, sprich in einer Datei für die jeweilige Datenbank, nur neu angelegte Tabellen werden in separate Dateien geschrieben. Umgekehrt bleiben diese Tabellen auch in einzelnen Dateien, wenn man die die Verwendung von Multi-Tablespaces wieder deaktiviert.
Auch hiernach werden nur die neu angelegten Tabellen wieder in die “globale” Shared-Space-Datei geschrieben.
Auf diese Weise kann man natürlich auch nur bestimmte Tabellen in einzelne Dateien schreiben und den “Rest” wie gewohnt in einer Datei vorhalten.

Da ich zur Zeit oft vor dem Problem stehe, dass ich aufgrund von vielen Einzeltabellen, die unter einer Merge-Table liegen, zu viele geöffnete Dateien habe, überlege ich, ob es in diesem Falle nicht sinnvoll wäre diese Tabellen in InnoDB in einen Shared-Tablespace zu legen…

[UPDATE]

Gute Idee, doch leider funktioniert die MERGE-Storage-Engine nicht mit InnoDB. Tja, schade.

16. Juli 2007

MySQL Seminar Unterlagen

Juhu, nachdem die Unterlagen zum MySQL-Performance-Tuning-Kurs, den ich kürzlich in Hamburg besucht habe, dort auf unerklärliche Weise abhanden gekommen sind, erreichte mich heute ein Päckchen aus den USA (offensichtlich Anti-Terror-Konform) mit den heiß ersehnten Unterlagen und dem versprochenen Geschenk.

Tja, statt der tollen Leder-Schreibmappe, die uns der Trainer dort gezeigt hat, gab’s leider nur nen Kugelschreiber und nen übergroßen Post-It Block. Hurra :) . Der Stift hat immerhin einen integrierten Textmarker, was ja mal ne nette Idee ist. Leider lässt sich dieser natürlich nicht nachfüllen oder austauschen und die Kugelschreibermine scheint auch eine Sondergröße zu sein, die man nirgends mehr nachkaufen kann. Naja, würde man eh nie tun, aber wenn sowas schon per Konstruktion zu einem Wegwerfartikel verdammt ist, finde ich sowas immer ausgesprochen ärgerlich.

MySQL Kugelschreiber

Egal, schöner Stift, freu ich mich trotzdem ;)