SQL'de yinelemeli/yinelemeli hesaplamaların gerçekleştirilmesi için birkaç yol vardır:
WITH RECURSIVE) — hiyerarşilerin (ağaçlar, grafikler, bağlantı zincirleri) dolaşımı gibi görevler için çalışır.Özyinelemeli CTE ne zaman kullanılmalı:
Örnek:
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;
Eğer özyinelemeli CTE görev çözmüyorsa veya veriler çok büyükse, diğer mekanizmalar (örneğin, dış işleme, geçici tablolar veya SQL dışı özel algoritmalar) uygulanır.
Özyinelemeli CTE sonsuz bir yürütmeye neden olabilir mi? Bunu nasıl önleyebiliriz?
Cevap:
Evet, eğer grafikte döngüler varsa (örneğin, parent_id tekrar bir alt öğeye referans verirse), özyinelemeli CTE döngüye girebilir. Çoğu DBMS, özyineleme katmanlarının maksimum sayısını sınırlama desteğine sahiptir (MAXRECURSION MS SQL için veya benzer bir seçenek). Her zaman özyineleme derinliğini sınırlamak iyi bir uygulamadır.
-- MS SQL Server OPTION (MAXRECURSION 100)
Hikaye
Finans projesinde, bağlı hesaplar (ebe-çocuk) zincirlerinden nihai bakiye hesaplıyorduk. Kullanıcılardan biri yapıda bir döngü oluşturdu (ebe kendi altı oldu). Sorgu sonsuz bir şekilde çalışmaya başladı ve sunucuyu yükledi. Döngü kontrolleri ve MAXRECURSION'ı ekledik, problem çözüldü.
Hikaye
Görev yönetim sisteminde bağımlı görevlerin durumunu gösterici işleviyle hesaplıyorduk. Özyinelemeli CTE'ye geçtikten sonra parent_id için optimal indeksleri unuttuk — her adımda maliyetli join işlemleri olduğu için performans 5 kat düştü.
Hikaye
Göstergelerle kategori ağacını dolaşma sorgusu doğru çalışıyordu, ancak 100.000 satırda 7 dakikada bitiyordu. "Yavaş" kabul edilen özyinelemeli CTE'ye geçince, kümelerle çalışan motorun optimizasyonu sayesinde aynı sonuç 5 saniyede elde edildi.