SQL Server sık kullandığımız group by işlemini yaparken ya Hash Match Aggregate ya da Stream Aggregate işlemlerinden birini seçecektir. İki işlem arasındaki farka daha önce değinmiştik. Stream Aggregate işlemi gruplanacak verinin sıralı olması durumunda veri kümesinin hızlıca gruplanabildiği bir operatörken, Hash Match Aggregate ise sıralı olmayan veri kümesi üzerinde sıralama işleminin maliyetli olduğu durumlarda tercih edilen ve veri kümesindeki değerler için bir Hash değeri hesaplayan ve bu değere göre gruplama yapan bir operatördür.
Gruplama işlemlerinde SQL Server o an yapacağı işleme göre uygun operatörü seçecektir, fakat bazı durumlarda bu seçimi SQL Server’a bırakmak yerine biz belirleyebilmekteyiz. Bunun için Hash Group veya Order Group ifadelerini kullanabiliriz. Hash Group ifadesi SQL Server’a Hash Match Aggregate kullanmasını, Order Group ise Stream Aggregate operatörünün kullanılmasını sağlamaktadır. Şimdi bu iki durumu örnek üzerinde inceleyelim.
Hash Group
İlk örneğimizde SQL Server’ın Stream Aggregate operatörünü kullandığı bir senaryoyu ele alalım. Aşağıdaki gibi sorgumuzu çalıştırıp Execution Planını inceleyelim.
select Color,
Sum(ListPrice)
from Production.Product
group by Color
Yukarıdaki sorgumuzun Execution Planı aşağıdaki gibidir.

Yukarıdaki resimde gördüğümüz gibi SQL Server Stream Aggregate operatörünü seçmiştir. Stream Aggregate operatörü için veri kümesinin sıralı olması gerekmektedir. Bu nedenle Clustered Index Scan operatörü ile veri kümesi okunduktan sonra Sort operatörü ile veriler sıralanmış ve Stream Aggregate operatörü tercih edilmiştir. Şimdi Stream Aggregate operatörünün üzerine gelerek çıkan Tooltip penceresinde Sub Tree Cost değerimizi inceleyelim.

Stream Aggregate operatörünün Estimated Sub Tree Cost değerini incelediğimizde 0,0314 değeri çıkmaktadır. Bildiğiniz gibi Estimated Sub Tree Cost değeri ilgili operatörün kendisine kadar olan operatörlerin toplam maliyetini göstermektedir. Şimdi aynı işlemi SQL Server’a Stream Aggregate yerine Hash Match Aggregate kullanarak yaptırıp değerlerimizi karşılaştıralım.
SQL Server’da sorgumuzda Stream Aggregate yerine Hash Match Aggregate operatörünün kullanılmasını istiyorsak bunu Hash Group ifadesi ile sağlayabiliriz. Şimdi sorgumuzu aşağıdaki gibi değiştirelim.
select Color, Sum(ListPrice) from
Production.Product group by
Color option(hash group)
Yukarıdaki gibi sorgumuzu değiştirdikten sonra Execution Planımızı inceleyelim.

Yukarıdaki resimde gördüğümüz gibi SQL Server aynı sorgu için artık Stream Aggregate operatörünü değil Hash Match Aggregate operatörünü kullanmış oldu. Bunun sebebi ise sorgumuza eklediğimiz option(hash group) ifadesi ile SQL Server’a gruplama işlemi için Hash Match Aggregate operatörünü kullanmasını belirtmemizdir. Şimdi yukarıdaki Execution planımızdaki Hash Match operatörünün detaylarını inceleyelim.

Hash Match Aggregate operatörünün Estimated Sub Tree Cost değerini incelediğimizde 0,0341 değeri çıkmaktadır. SQL Server’ı Hash Match Aggregate operatörünü kullanmaya zorladığımızda az da olsa performansımızın düştüğünü görebiliriz. Bu da aslında SQL Server’ın çok büyük ihtimalle doğru işlemi seçtiğini göstermektedir.
Order Group
Yukarıdaki işlemimizde SQL Server’ın gruplama işlemi için Stream Aggregate operatörünü seçtiği durumlarda bu operatör yerine SQL Server’a Hash Match Aggregate operatörünü kullandırdık. Şimdi de tam tersi bir durumu inceleyelim yani SQL Server’ın Hash Match Aggregate operatörünü seçtiği durumda SQL Server’a Stream Aggregate operatörünü kullandıralım. Bu durum için örnek sorgumuz aşağıdaki gibidir.
select SalesPersonID,
Sum(TaxAmt) from [Sales].[SalesOrderHeader]
group by SalesPersonID
Yukarıdaki sorgumuzun Execution Planını inceleyelim.

Yukarıdaki resimde gördüğümüz gibi SQL Server sorgumuzun çalıştırılması için Hash Match Aggregate operatörünü seçmiştir. Bildiğiniz gibi Hash Match Aggregate operatörü genelde veri kümesinin sıralı olmadığı ve sıralama maliyetinin yüksek olduğu durumlarda SQL Server tarafından tercih edilmektedir. Şimdi SQL Server’a aynı sorguda Stream Aggregate operatörünü kullandıralım. Bunun için sorgumuza Order Group ifadesini ekleyerek çalıştırıp Execution Planımıza bakalım.
select SalesPersonID, Sum(TaxAmt) from [Sales].[SalesOrderHeader]
group by SalesPersonID
option(order group)
Yukarıdaki sorgumuzun Execution Planı aşağıdaki gibi olacaktır.

Execution Planımızda SQL Server’a Stream Aggregate operatörünü kullandırdığımız için SQL Server öncelikle Sort operatörünü kullanarak veri kümesini sıraladıktan sonra Stream Aggregate operatörünü gruplama işlemi için kullanmış oldu.
Not: SQL Server çok büyük ihtimalle Execution planda doğru operatörü seçecektir. Fakat bazı durumlarda veri indeksten sıralı olarak okunsa bile SQL Server gruplama işlemi için Hash Match Aggregate operatörünü seçebilmektedir. Bu gibi durumlarda zaten veri sıralı ise SQL Server’a Stream Aggregate operatörünü kullandırmak gerekebilmektedir.
Bu makalede execution yapılarında görülen Hash Group ve Order Group Query Hint ifadesine değinmiş olduk. Başka bir makalede görüşmek dileğiyle..
“ Eğer anne baban, hakkında bilgin olmayan bir şeyi bana ortak koşman için seni zorlarlarsa bu durumda onlara uyma ama yine de onlara dünyada iyi davran; yüzünü ve özünü bana çevirenlerin yolunu izle. Sonunda dönüşünüz yalnız banadır. O zaman yapıp ettiklerinizin sonucunu size bildireceğim.”Lokman-15