MSSQL Server Merge Join Türü

Bu makalede MSSQL Server Merge Join türünü 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 ilk olarak execution planda sıklıkla karşılaştığımız Merge Join türüne değinelim:

Fiziksel join türlerinin en “zarifi” ve hızlısıdır, ancak çok katı bir şartı vardır: Her iki veri setinin de join sütununa göre sıralı (sorted) olması gerekir.

  • Çalışma Mantığı: Her iki tablo aynı anda okunur ve bir fermuar gibi eşleştirilir. Sıralı oldukları için her iki tablo üzerinden sadece bir kez geçilir.
  • Neden Görürsünüz?
    • Join sütunları üzerinde Clustered Index varsa (veri zaten sıralıdır).
    • Sorguda bir ORDER BY varsa ve Optimizer veriyi zaten sıralamışsa.
    • Büyük veri setleri birleştiriliyorsa.

Merge Join genellikle sağlıklıdır. Ancak, Execution Plan’da Merge Join’den hemen önce bir “Sort” operatörü görüyorsanız dikkat! SQL Server veriyi birleştirmek için önce bellekte sıralama yapıyordur. Bu maliyetlidir. Bu durumda ilgili sütunlara index ekleyerek “Sort” adımını ortadan kaldırabilirsiniz.

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.

Nested Loops’tan farklı olarak Merge Join’de “Outer/Inner” yerine genellikle iki eşit girişten bahsedilir. Ancak hangisinin üstteki (first) giriş olduğunu Where (join columns) kısmından anlarız:

  • Birinci (Üst) Tablo: [SalesOrderHeader]. SQL genellikle eşitliğin soluna ilk girişi yazar.
  • İkinci (Alt) Tablo: [Customer].
  • Eşleşme Sütunu: Her iki tabloda da CustomerID üzerinden birleştirme yapılıyor.

Bu görselde SQL Server’ın tahmin yeteneği harika görünüyor:

  • Actual Number of Rows: 31.465 (Gerçekte dönen satır).
  • Estimated Number of Rows for All Executions: 31.294,3 (Tahmin edilen satır).

Tahmin ile gerçek neredeyse birebir aynı. Bu durum, bu tabloların istatistiklerinin güncel olduğunu ve SQL Server’ın en doğru join türünü (Merge Join) seçtiğini kanıtlar.

Many to Many: False. Bu çok önemli bir bilgi. Bu, join yapılan sütunlardan en az birinin (muhtemelen Customer tablosundaki CustomerID) Unique (Benzersiz) olduğunu gösterir. SQL Server, her iki tarafın da CustomerID sütununa göre sıralı (sorted) olduğunu bildiği için (muhtemelen her ikisinde de bu sütun üzerinde Cluster Index var), veriyi bir fermuar gibi birleştirmiş. Bu en hızlı join yöntemlerinden biridir.

Estimated Operator Cost: %49. Bu sorgunun toplam yükünün yarısı bu join işlemi sırasında oluşuyor. Ancak bu korkutucu bir değer değil, çünkü 31 bin satırlık bir veri seti işleniyor. Merge Join burada olabilecek en optimize tercihtir.

Alt kısımda gördüğün Residual alanı, join işlemi bittikten sonra SQL’in hala kontrol etmesi gereken bir filtre olup olmadığını söyler. Burada yine CustomerID eşleşmesini görüyorsun. Bu, join motorunun verileri eşleştirirken kullandığı nihai mantıksal süzgeçtir.

Join işleminde bulunan tabloların join’lenen 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.

Join TürüTercih Edilen DurumGereksinimBellek Kullanımı
Nested LoopsKüçük veri / İyi Indexİç tabloda IndexÇok Düşük
Merge JoinBüyük veri / Sıralı veriSıralı giriş (Index)Düşük
Hash JoinBüyük veri / Indexsiz veriYokYüksek

Bu makalede MSSQL Server Execution Plan’ Join Türleri ‘da görülen Merge Join türünü detaylı bir şekilde görmüş olduk. Başka bir makalede görüşmek dileğiyle..

Kötülüğe iyilikle karşılık verin.Fussilet-34

Author: Yunus YÜCEL

Bir yanıt yazın

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