Bu makalede MSSQL Server Execution Plan Hash Match Aggregate Operatörünü detaylı bir şekilde görmüş olacağız. Sql server sorgularda herhangi bir kolunu guruplamak için group by ifadesi kullanılması gerekmektedir. Ayrıca tekilleştirmek için DISTINCT operatörünün kullanılması gerekmektedir. Sorgularda kullanılan bu ifadelerin execution plan yapımızda Hash Match (Aggregate) olarak karşımıza çıkmaktadır.

Yukarıdaki sorgumuzda city kolunu gruplandığı için Hash Match(Aggregate) operatörünün kullandığını görmekteyiz.
Hash Match Aggregate iki aşamadan oluşur:
- Build Aşaması: SQL Server, giriş satırlarını okur. Her satırın gruplanacak sütununa (örneğin MusteriID) bir hash fonksiyonu uygular ve sonucu hafızada (Memory) oluşturduğu bir hash tablosuna yazar.
- Probe/Output Aşaması: Aynı hash değerine sahip satırlar toplandıkça (SUM, AVG gibi işlemler yapılarak), sonuçlar hash tablosundan çekilip çıktı olarak verilir.
SQL Server gruplama işlemi yaparken de gruplayacağı verileri ve değerleri tutmak için bellekte bir tane Hash Table oluşturup verileri geçici olarak burada tutar. Örneğin bizim sorgumuzda verilerimizi City değerine göre kaçar adet olduklarını listelemek istedik. SQL Server bu işlem için bellekte City değerini ve buna karşılık ilgili değerden kaç adet olduğunu tutacak bir tablo oluşturur.
Gruplama işlemlerinin de maliyetleri diğer işlemlere nazaran yüksektir bu yüzden gruplama yaparken de diğer işlemlerde olduğu gibi gerekli indekslerin kullanılmasına özen gösterilmeli ve mümkünse koşul ifadeleri ile üzerinde gruplama işlemi yapılacak olan veri kümesi küçültülmelidir.
Avantajları
- Sıralama Gerektirmez: Stream Aggregate operatörünün aksine, giriş verisinin sıralı (Indexed) olmasına gerek duymaz.
- Büyük Veri Setlerinde Hızlıdır: Çok büyük ve sırasız veri yığınlarını işlemek için genellikle en verimli yoldur.
- Paralel Çalışmaya Uygundur: Çok çekirdekli işlemcilerde (Parallelism) oldukça performanslı bir şekilde bölünebilir.
Dezavantajları
- Memory Kullanımı: Hash tablosu oluşturmak için RAM kullanır. Eğer veri seti çok büyükse ve SQL Server’a ayrılan bellek yetmezse, veriyi diskteki tempdb’ye yazar (Spill to TempDB). Bu da performansı ciddi oranda düşürür.
- Bloklayıcı Operatör: Tüm veriyi okuyup hash tablosunu oluşturmadan ilk satırı döndüremez (Blocking Operator). Bu, “ilk satırı hızlı alma” (Low Latency) senaryoları için kötüdür.
Eğer bir sorgu planında bu operatörü görüyorsanız ve performans sorunu yaşıyorsanız şu adımları izleyebilirsiniz:
- Eksik İndeks Kontrolü: Eğer GROUP BY yaptığınız kolonlar üzerinde uygun bir indeks olsaydı, SQL Server muhtemelen çok daha hafif olan Stream Aggregate operatörünü kullanacaktı. İlgili kolonlara “Non-Clustered Index” eklemeyi düşünün.
- İstatistikleri Güncelleyin: SQL Server, tablodaki veri miktarını yanlış tahmin ederse (Cardinality Estimation), yanlışlıkla Hash Match seçebilir. UPDATE STATISTICS komutuyla istatistikleri tazeleyin.
- Bellek Kullanımını İzleyin: Operatör üzerinde sarı bir ünlem işareti varsa, bu “Spill to TempDB” uyarısıdır. Bu durumda ya sunucunun belleğini artırmalı ya da işlenen veri miktarını (filtrelerle) azaltmalısınız.
- Sütun Sayısını Azaltın: GROUP BY içinde ne kadar çok ve büyük veri tipi (nchar, varchar(max) vb.) varsa, hash tablosu o kadar büyür. Sadece ihtiyacınız olan kolonları gruplayın.
Bu makalede execution yapılarında görülen Hash Match Aggregate ifadesine değinmiş olduk. Başka bir makalede görüşmek dileğiyle..
“Ey insan! Seni yaratan, şekillendirip ölçülü yapan, dilediği bir biçimde seni oluşturan cömert Rabbine karşı seni ne aldattı?” İnfitar-6-8
