Sorunun Tarihi:
İç içe sorgular, SQL'de dilin ifade yeteneklerini genişletmek ve basit SELECT operatörlerine sığmayan karmaşık iş problemlerini çözmek için başlangıçta tasarlanmıştır. Ancak veri hacimlerinin artması ve ilişkisel modellerin karmaşıklaşmasıyla birlikte, iç içe sorguların her zaman etkili çalışmadığı gerçeği anlaşılmıştır: bu, belirli bir DBMS'in optimizasyoncunun uygulanmasına bağlıdır.
Sorun:
Ana zorluk, okunabilirlik, mantık doğruluğu ve performans arasında bir uzlaşma bulmaktır. İç içe sorgu her zaman join işlemlerine optimize edilmez ve sık sık maliyetli döngülere dönüşür (Nested Loops).
Çözüm:
Kod örneği:
-- SELECT içinde iç içe sorgu (dikkatli!) SELECT name, (SELECT COUNT(*) FROM orders WHERE orders.client_id = clients.id) AS order_count FROM clients; -- JOIN ile eşdeğer (genelde daha hızlı): SELECT clients.name, COUNT(orders.id) AS order_count FROM clients LEFT JOIN orders ON orders.client_id = clients.id GROUP BY clients.name;
Ana özellikler:
SELECT içinde iç içe sorgu, karşılık gelen LEFT JOIN'dan daha hızlı mı çalışır?
Çoğu zaman — hayır. SELECT içindeki korelasyonlu iç içe sorgu, dış sorgunun her satırı için çalıştırılırken, JOIN bir kez indekslerle tüm tablo için oluşturulur.
CTE (WITH) yerine FROM'da iç içe sorgu kullanabilir miyiz ve fark yaratır mı?
Evet, FROM'daki iç içe sorgu:
SELECT t1.id, sub.agg FROM table1 t1 JOIN (SELECT id, MAX(val) AS agg FROM table2 GROUP BY id) sub ON t1.id = sub.id;
Ama CTE bazen daha fazla okunabilirlik sunar ve yürütme planlarında farklı bir optimizasyona yol açabilir.
Tüm iç içe sorgular, benzer JOIN'lere optimize edilir mi?
Hayır. Tüm DBMS'lerin bunu aynı şekilde yapamadığı durumlar vardır; bazen iç içe sorgu her satırın taranmasına neden olur, özellikle dış ve iç sorgu arasında bir korelasyon varsa.
Satış yöneticisi, içteki SELECT ile siparişlerin sayısını hesaplayarak bir müşteri raporu yaptı. İşlem süreleri — dakikalar, sunucu üzerindeki yük geometrik bir şekilde arttı.
Artılar:
Sorgu, LEFT JOIN ve gruplama ile yeniden yazıldı.
Artılar: