Es gab SQL vor Window Functions und es gibt SQL nach Window Functions

… so fängt ein lesenwertes Tutorial für dieses Thema an, das beim Einstieg erst einmal recht sperrig ist.

Wenn man sich da aber etwas durchwühlt, dann merkt man wie genial das ganze ist – CTE+Window-Function=Pr0n. Bis man aber dahin kommt, braucht’s einfach erst einmal ein bisschen mehr Brainfuck als im Alltag oft möglich ist. Darum will ich hier mal den allersimpelsten Fall zeigen, weitermachen kann man dann eben z.B. mit dem obengenannten Artikel.

Ich baue eine Suchfunktion für unsere Produktdatenbank. Schnell muss es sein, Prefix-Suche muss unterstützt werden, es wird natürlich paginiert. Also brauche ich nicht nur die aktuell dargestellten Produkte, sondern auch immer eine Gesamtzahl.

Traditionell macht man das so:

Die Abfragen brauchen beide ca. 5 ms – und natürlich auch zwei Round-Trips zur Datenbank. „Doof“, denkt man sich, „das muss doch auch mit einem Trip gehen“. Richtig. Erste Wahl ist da natürlich die simpelste Window Function:

„Cool“, denkt man sich, „so passt der Lack“. EXPLAIN ANALYZE belehrt einen aber, dass WINDOW-Funktionen eben eher für Windows gedacht sind, also unterschiedliche Datenabschnitte pro Tupel – und nicht für das ganze Brett. Denn die Window-Funktion wird für jede Zeile ausgeführt – Ausführungszeit von dieser Abfrage daher um die 100ms. Wir haben uns zwar den Trip zur Datenbank gespart, aber dafür die Ausführungszeit verzehnfacht.

In dem Fall besser keine Window-Funktion benutzen (die Dinger sind für moving averages, zum Kurvenglätten u.ä. hervorragend), sondern z.B. eine CTE:

Die braucht ca. 7-9 ms, also in etwa genauso lang wie die beiden separaten Abfragen für Count und Seite, aber spart einen Trip zur Datenbank.

Kommentar verfassen