MSSQL Server Execution Plan Join Türleri

Bu makalede MSSQL Server join türlerini ele almış olacağız. Sql server da kullanıcı bir sorgu yazarken inner-left-full-right-cross join türleri olan mantıksal join yapılarını kullanmaktadır. Sql server kullanıcı sorgularını arka tarafta fiziksel olarak hangi  join yapısına dönüştüğünü detaylı bir şekilde ele almış olacağız.

Şimdi sql server arka planından bulunan Fiziksel Operatörlere kısacası değinmiş olalım.

SQL Server, bizim TSQL ile yazdığımız JOIN ifadelerini arka planda aşağıdaki join türlerine dönüştürür.

NESTED LOOPS JOIN

 Sorgularımızın Execution planımızda ilgili operatörün Tooltip penceresi inceleyebiliriz.

Tablolardan birini iç(inner) diğerini ise dış(outer) olarak işaretler ve outer olarak işaretlenen tablodaki her satır için inner olarak işaretlenen tablodaki her satırı okur. Kısacası sıralı bir şekilde outer tablosunda her değeri inner tablosundaki tüm satırlar karşılaştırır. Bu şekilde birleştirme işlemi yapılmaktadır.

Eğer tablolardan biri küçük ve diğeri büyükse ve büyük tablonun join kolonunda index varsa bu join türü çok performanslı çalışacaktır.

Outer olarak işaretlenen tablonun join yapılan kolonunda index varsa çok performanslı çalışacaktır. Karmaşıklığı O(NlogM) dir.

Not: Birleşime girecek tabloların birinde indexs tanımlı diğerinde yoksa ise bu join işlemi kullanılmaktadır. Genellikle oluşan execution planda bu yapı karşımıza çıkmaktadır.

Not: Bu yapıda satır satır okuma işlemi yapılmaktadır. Bu şekilde çalışan operatörlere Non Blocking operatörler denilmektedir.

MERGE JOIN

Aşağıdaki resimde dikkat ederseniz iki tablomuzda sıralı bir şekilde görülmektedir. İlk tabloda A değerine bakıp ikinci tabloda A değeriyle eşlenir daha sonra ikinci tablo B değerine geçer ilk tabloda otomatik olarak B değerine geçer. Eş kolonlardaki değerler bittikten sonra aynı olanlar match olur. Daha sonra sıra ile aşağı tarafa gidilmektedir. Nested yapısında ise A değerini ikinci tabloda ister bulsun ister bulmasın tablonun hepsini taramaktadır.

Sorgularımızın Execution planımızda ilgili operatörün Tooltip penceresi inceleyebiliriz.

Merge Join birleştirilen iki tablonun birleştirme için kullanılan sütunları daha önceden sıralanmış ise SQL Server tarafından tercih edebilen bir operatördür. Şimdi yukarıda gördüğümüz Merge Join operatörümüzün Tooltip penceresini inceleyelim. Where (Join Columns) kısmında birleştirme işlemi yapılırken SalesOrherHeader tablosundan CustomerID ve Customer tablosundan CustomerID kolonlarının kullanıldığını görüyoruz. Bu iki değer birleştirme için kullanılan tablolarda sıralanmış olarak tutulduğu için SQL Server Merge Join işlemini tercih etmiştir. SQL Server Join işlemi ile karşılaştığında öncelikle birleştirme için kullanılacak koşuldaki değerlerin sıralı olup olmadığına bakar.

Eğer sıralıysa diğer Join işlemlerinden daha performanslı çalışan Merge Join operatörü tercih edilir.

Eğer sıralı değilse SQL Server ya veriyi sıralar ya da diğer Join operatörlerinden birini tercih eder. Bunu yaparken de sıralama maliyeti ile diğer operatörü kullanıldığında ortaya çıkacak maliyeti değerlendirip ona göre bir seçim yapar. 

Join işleminde bulunan tabloların joinlenen kolonları arasında index varsa merge join execution plan yapımızda kullanılacak operatördür.

Aşağıdaki örnekte AdventureWorks veritabanı üzerinde join’leme işleme yaptığımızda, join’e giren kolunlar arasında index yapımız aktifse  merge join operatörü kullanılmaktadır.

Böyle bir join sonucunda join’e girecek kolonların ikiside sıralı yapıda olduğu için merge join çok performanslı çalışacaktır.

Merge Join sıralı olan bu iki kolon ile yapılan bir join işleminde iki kolonu karşılaştırır ve eşitse sonuç olarak döndürür. Karmaşıklığı O(N+M) dir. O(N) de diyebiliriz.

HASH Match JOIN

Execution plan yapımızda bulunan  Hash Match operatörün Tooltip penceresinde bu kavramın ne işe yaradığına değinelim.

Tercih edilmeyen bir join türüdür. Execution plan yapımızda join işleminin temsil edildiği bir yapı olarak karşımıza çıkmaktadır. İki veri kümesinden gelen değerleri birleştirmek için kullanılır. Eğer tablolarımız büyük, herhangi bir index yapısına sahip değil ve sırasız bir şekilde oluşturulan tablolar herhangi bir join işlemine girerse sql server iki tabloyu birleştirmek için Hash Match Join operatörü kullanılmaktadır.

Hash Match operatöründe Birleştirme yapılırken öncelikle bellekte küçük tablomuza  uygun bir Hash Table oluşturulur, daha sonra ikinci büyük tablomuzdaki veriler okunmaya ve mevcut hash tablodaki verilerle karşılaştırılmaya başlanır. Birbirini ile uyumlu olan kayıtlar hash tabloda saklanıp diğer veriler silinir ve böylece iki veri kümesinin birleştirilmesiyle elde edilmiş bir tablo oluşturulur.

İki tablodan küçük olan belleğe alınarak bir hash table oluşturulur. Daha sonra büyük tablo taranır ve büyük tablodaki hash değeri ile bellekteki hash table’daki hash değeri karşılaştırılarak eşit olanlar sonuç listesine eklenir.

Not: Join işlemine girecek tablolarda hiç index olmadığında bu tabloların birleşimi için Hash Match operatörü kullanılmaktadır.

Şimdi yukarıda belirtilen Tooltip açıklamasına gelirsek öncelikle Logical Operation değeri Inner Join işlemi yapıldığını belirtmektedir. Hash tabloya veriler eklenirken bu logical operatör dikkate alınmaktadır. Dikkat edilmesi gereken diğer nokta ise Output List kısmında bulunan değerlerdir.  Dikkatli incelenirse 3 farklı tablodan değerlerin alınıp birleştirildiği görülmektedir.

Hash Keys Probe kısmı ise Hash işleminde kullanılacak olan değeri belirtmektedir.

Hash Match operatörü birleştirilen tablolardan birinde az diğerinde ise çok fazla kaydın bulunduğu durumlarda daha performanslı sonuç vermektedir. Aksi takdirde iki tane büyük tablo birleştirilmesi için Hash işleminin kullanılması sorgumuzun performansı olumsuz etkiler. Ayrıca Hash Match operatörü birleştirilecek olan tablolar üzerinde SQL Server’ın kullanabileceği bir indeks yoksa SQL Server iki tablodaki verileri Hash Match işleminden geçirerek birleştirir. Yani aslında Hash Match operatörünün kullanıldığı bir Execution plan için kabaca eksik bir indeks olduğu veya koşul operatörünün yanlış yapılandırıldığı anlamını çıkarabiliriz. Bu yüzden Hash Match operatörünün yer aldığı Execution planlarımızı yeniden gözden geçirip yapılabilecek herhangi bir düzelme olup olmadığını kontrol edebiliriz.

Kısacası Hash Match çoğunlukla sıralı olmayan büyük tablolar üzerinde birleştirme işlemi gerçekleşeceği zaman kullanılır. Birleştireceği tablolar arasında öncelikli olarak küçük olan tabloyu alır ve bellekte hash function kullanarak bir hash tablo oluşturur. Ardından diğer tablo üzerinde teker teker gezer ve her veriyi aynı hash function’a sokar çıkan değer oluşturulan hash tablosunda mevcut ise bu kayıtları birleştirir. Bu sayede join işlemini gerçekleştirir ama kaynak kullanımı(cpu ve bellek) çok fazla olduğundan dolayı maliyeti yüksektir.

Peki ne yapabiliriz, öncelikle eğer bu iki tablo scan işlemleri sonucunda gelip birleştirilecek ise bu tablolar için index atılabilir bu sayede hem veri seti küçültülür hem de veri sıralanmış olur. Karmaşıklığı O(N*M) dir.

Bu makalede MSSQL Server Execution Plan Join Türleri detaylı bir şekilde görmüş olduk. Başka bir makalede görüşmek dileğiyle..

Kadir gecesi, bin aydan daha hayırlıdır. Kadir Suresi, 3. Ayet

Author: Yunus YÜCEL

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir