... das Problem bei komplexen SQL Abfragen ist die Reihenfolge der Ausführung der Bestandteile des Statements in Abhängigkeit von der gewählten Zugriffsstrategie. Da kann ich mir sauber ausgedacht haben, bestimmte Sätze in der where Klausel wegzuschmeißen und der Query Optimizer entscheidet sich; da mache ich eine Zwischentabelle, über die ich dann einen full tablescan mache...
Das kann selbst dann passieren, wenn ich Bedingungen, die nur für eine Tabelle gelten in die join Klausel packe (was man immer tun sollte); auch da gibt es noch den Aetsch Zweig des Query Optimizers (da mache ich einen cross join und dann einen full table scan...)

Verschärft hat sich das Problem durch komplexere Statements und Verbesserungen der Query Engine in Folge schnellerer Hardware: je schneller die Hardware, umso eher sind Full table scan und temporäre Index by the fly von Vorteil (oder werden dafür gehalten).

Birgittas Vorschlag das in eine View zu verschieben, klingt gut, funktioniert aber genauso wenig wie ein CTE (common table Expression), da der Query Optimizer die Freiheit hat, die Bedingungen der View in das SQL Statement aufzunehmen - und dann bin ich sogar weiter weg von der Lösung (da man nicht direkt sieht, was in der View an Bedingungen und Konvertierungen steht). Es gibt in SQL keine stringente Möglichkeit der Query Engine eine Reihenfolge der Auswertung vorzuschreiben! (momentan geht noch die Verlagerung in eine stored Procedure oder eine UDTF, sobald der Optimizer da rein guckt, um das noch zu optimieren...) Selbst wenn der Query Optimizer nicht im Recht ist, weil die Umwandlung des SQL Statements nur fast äquivalent war, hilft mir das wenig und mit der Komplexität nimmt die Wahrscheinlichkeit von Bugs in der Query engine zu.

Huddelfreie Daten helfen Probleme zu vermeiden, aber auch das nicht immer (wenn z.B. ein Fulltable scan über einen cross join einfach zu langsam wird...) und viel zu oft hat man auch strukturellen Huddel in den Daten.

Macht man BI in einem "echten" Daten-Karstadt (AKA DWH), sollte das der ETL Prozess leisten (das T steht für Transform und da wird der Müll aus den Daten raussortiert, bzw. zu verwertbaren Daten recycelt). Versucht man BI auf Rohdaten, muss man Teilbereiche denormalisieren, im einfachsten Fall, indem man Extrakte zieht, die man dann weiterverarbeitet (aus einem SQL Statement werden dann mehrere, die temp tables erstellen, die man weiterverarbeitet), damit löst man viele Problem, aber nicht alle...

Die zweite Technik sind dann statische Hilfstabellen (habe ich am Beispiel einer Zeit Hierarchie in einem vorherigen Beitrag erläutert); das geht aber nur bei Wertebereichen mit überschaubarer Kardinalität so einfach.

Die nächste Stufe sind dann gleichartige Hilfstabellen, deren Größe man dadurch im Zaume hält, dass man nur das reinnimmt, was tatsächlich vorkommt (damit kann man selbst abenteuerliche Problem, wie numerische Daten in Alphafeldern, in denen noch eins, zwei drei oder Zahlen plus Währungsbeträge oder null komma nix drinsteht heilen). Da erstellt man vorab eine bereinigte Umsetztabelle, die man dann joined; will man die immer adhoc haben, kann man die auch per Trigger auf die Originaltabelle mit pflegen und aktuell halten.

D*B