In SQL gibt es mehrere Möglichkeiten, iterative/reursive Berechnungen durchzuführen:
WITH RECURSIVE) — funktionieren für Aufgaben wie das Durchlaufen von Hierarchien (Bäume, Grafiken, Verweisketten).Wann rekursive CTE verwenden:
Beispiel:
WITH RECURSIVE tree AS ( SELECT id, parent_id, name, 1 AS level FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.parent_id, c.name, t.level + 1 FROM categories c JOIN tree t ON c.parent_id = t.id ) SELECT * FROM tree;
Wenn der rekursive CTE das Problem nicht löst oder die Daten zu umfangreich sind, werden andere Mechanismen eingesetzt (z.B. externe Verarbeitung, temporäre Tabellen oder spezialisierte Algorithmen außerhalb von SQL).
Kann ein rekursiver CTE zu einer unendlichen Ausführung führen? Wie kann man das verhindern?
Antwort:
Ja, wenn der Graph Zyklen enthält (z.B. wenn parent_id sich wieder auf einen Nachfahren bezieht), kann ein rekursiver CTE in eine Schleife geraten. Die meisten DBMS unterstützen eine Begrenzung der maximalen Anzahl von Rekursionsebenen (MAXRECURSION für MS SQL oder eine ähnliche Option). Eine gute Praxis ist es, immer die Rekursionstiefe zu begrenzen.
-- MS SQL Server OPTION (MAXRECURSION 100)
Geschichte
In einem Finanzprojekt wurde der Endsaldo von verknüpften Konten (parent-child) über einen rekursiven CTE berechnet. Einer der Benutzer hatte einen Zyklus in der Struktur geschaffen (der Elternteil wurde zum Nachkommen). Die Abfrage begann unendlich zu laufen und belastete den Server. Es wurde eine Zyklusprüfung und MAXRECURSION hinzugefügt, das Problem wurde gelöst.
Geschichte
Im Aufgabenmanagementsystem wurde der Status abhängiger Aufgaben durch cursorbasierte Verarbeitung berechnet. Nach der Migration zu rekursiven CTEs wurden die optimalen Indizes nach parent_id nicht berücksichtigt — die Leistung fiel um das 5-fache, da bei jedem Schritt kostspielige Join-Operationen stattfanden.
Geschichte
Die Abfrage zum Durchlaufen des Kategorienbaums mit einem Cursor funktionierte korrekt, benötigte jedoch 7 Minuten für 100.000 Zeilen. Wir haben es auf einen rekursiven CTE umgeschrieben, der als "langsam" galt — und erhielten das gleiche Ergebnis in 5 Sekunden dank der Optimierung durch die Aggregationsmotor.