Tarihsel olarak SQL'deki agregasyon ve gruplama görevleri, genellikle raporlar ve analitik için ortaya çıkmıştır. 80'lerdeki ilişkisel veritabanı yönetim sistemlerinde (RDBMS) temel agregat fonksiyonlar (SUM, COUNT, AVG) ortaya çıkmaya başlamıştır, ancak büyük veri setlerinde klasik GROUP BY yavaşlamaktadır. Ölçeklenebilirlik sorunu ortaya çıkıyordu: on milyonlarca kaydı ve birden fazla grubu içeren sorgular tabloları blokluyor ve işlemleri yavaşlatıyordu.
Sorun şu ki, etkisiz bir yaklaşımda SQL sunucusu sıralama, ara tablolar ve diskten okuma için çok fazla kaynak harcamaktadır. Özellikle, gruplama birden fazla sütun üzerinden veya dinamik bir agregat veri setiyle yapıldığında zorlaşır.
Çözüm, gruplama sütunları üzerinde doğru indekslerin oluşturulması, partitioning (bölümlendirme), "yarı agregasyon" ve sorgu yapısının optimize edilmesinde yatmaktadır. İş analitiği görevleri için sıklıkla yapılandırılmış Common Table Expressions (CTE), mallezi edilmiş görünümler ve pencere fonksiyonları kullanılır.
Kod örneği:
WITH PreAgg AS ( SELECT customer_id, region, SUM(amount) AS total_amount FROM sales WHERE sale_date >= '2024-01-01' GROUP BY customer_id, region ) SELECT region, COUNT(DISTINCT customer_id) AS customers, SUM(total_amount) AS region_amount FROM PreAgg GROUP BY region ORDER BY region_amount DESC;
Anahtar özellikler:
GROUP BY'ın performansı SELECT'teki sütun sırasına bağlı mı?
Hayır, SELECT'teki sütun sırasının hızı üzerinde etkisi yoktur, kritik olan gruplamanın yapıldığı sütunlar ve bunlar üzerine bir indeksin olup olmadığıdır.
GROUP BY ile her bir sütun için SELECT'te agregat fonksiyonu belirtmek zorunlu mu?
Zorunlu değildir, eğer sütun GROUP BY'da yer alıyorsa, agregasyon olmadan çıkartılabilir. Eğer sütun gruplamada yer almıyorsa, kesinlikle agregat edilmelidir.
SELECT department, MIN(salary) FROM employees GROUP BY department;
Bir GROUP BY'ı diğerine yerleştirip çok seviyeli agregasyon yapabilir miyiz?
Evet, iç içe geçmiş CTE veya alt sorgular "çok katmanlı" agregasyonlarla ara sonuçlar elde etmeyi sağlar.
WITH Step1 AS ( SELECT customer, SUM(amount) AS cust_sum FROM orders GROUP BY customer ) SELECT COUNT(*) FROM Step1 WHERE cust_sum > 10000;
Bir analist, indeksler ve örneklem bölme olmadan 200 milyon kayıtlı bir tablo üzerinde çok sayıda GROUP BY ile bir rapor oluşturmaktadır, ofis sabah 9'da "donmaktadır". Çalıştırma 40 dakika sürmektedir.
Artılar:
Eksiler:
Mühendis, ön filtreleme için CTE kullanır, gereken alanlar üzerinde akıllı indeksler oluşturur ve agregasyonu birkaç aşamaya böler. Rapor 5 saniyede oluşturulmaktadır.
Artılar:
Eksiler: