MySQL Union Statements

Gegeben ist eine SQL-Query die mittels UNION zwei Tabellen vermischt und die 50 aktuellsten Datensätze nach Timestamp ausgibt. War mal schnell, mit ein paar mehr Datensätzen nicht mehr. Die Abfrage läuft ca. 5 Sekunden – zu lange, denn es geht auch schneller.

Derartige Queries lassen sich wie folgt beschleunigen:
- UNION ALL anstelle von UNION, das Aussortieren der ggf. doppelten Datensätzen über ein WHERE geht schneller, als das per default genutzte UNION DISTINCT … nicht wundern, ist so.

Damit sinkt die Laufzeit der Query von ca. 5 auf ca. 1,5 Sekunden, aber da geht noch mehr (der eigentlich logische Teil *hust*):
- wenn möglich sollte man die abzufragenden Datenmengen Inner-Queries entsprechend klein halten, wenn man z.B. eh nur 50 Datensätze aus 2 Tabellen kombinieren will, dann ist es sinnvoll auch nur diese in die Gesamtmenge einzubringen.

Laufzeit der Query nun wieder im Millisekundenbereich. Fertig ;)

About Tobias Scherbaum

Sysadmin. Autor. Gentoo-Evangelist.
This entry was posted in Sysadmin. Bookmark the permalink.

One Response to MySQL Union Statements

  1. Ingo Krabbe says:

    Das eine geschickt formulierte where Klausel schneller geht als ein
    union distinct ist eigentlich ziemlich leicht zu begreifen, wenn man sich den
    Unterschied zwischen where und having ansieht:

    * Where selektiert Datensätze aus der Datenbank und erzeugt die
    Ergebnismenge
    * Having filtert die Ergebnismenge und verkleinert damit die
    Ausgabemenge
    * Union nimmt beide Ausgabemengen und union distinct würde
    also die Vereinigung beider Ausgabemengen nochmal filtern, wobei distinct ja
    eine Sortierung der Ausgabemenge vorraussetzt, um die dopplungen zu erkennen.

    Bei weitem die schnellste logische Methode um Datenmengen aus verschiedenen
    Tabellen zu kombinieren ist ein inner join mit vernünftigen on und
    where Selektoren.

    Etwas schwieriger und langwieriger ist die Auswahl von Datensätzen deren
    Bedingung eben nicht erfüllt ist:

    select x.* from x left join y on x.id=y.id where y.id is NULL;

    Also alle Zeilen aus x, die keine Entsprechung in y haben.

    Aber immer gilt die Regel, dass join und where vor der Erzeugung der
    Ergebnismenge, schneller sind als union. Beim join muss man nur Aufpassen, dass
    man nicht zu viele Datensätze erzeugt, da ohne Bedingung count(x) * count(y)
    Datensätze geliefert werden. Mit der richtigen on Bedingung (zum
    Beispiel mit dem Vergleich eines unique keys) bleiben sehr schnell nur noch
    wenige Datensätze übrig.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">