Bu makalede MSSQL Server Spool kavramlarını sırasıyla detaylı bir şekilde ele almış olacağız. Spool kavramı sql server yapısında performansı arttırmak için kullanılan bir yapı olarak karşımıza çıkmaktadır. Genellikle execution plan yapılarında karmaşık olan işlemlerinde karşımıza çıkan bir yapıdır.
SQL Server’da Spool operatörleri, sorgu işlemcisinin (Query Processor) ara sonuçları geçici olarak saklayıp (genellikle tempdb üzerinde) tekrar kullandığı mekanizmalardır. Temel mantığı, “bir kez hesapla, defalarca kullan” prensibine dayanır.
Spooling genellikle performansı artırmak için kullanılır ancak bazen büyük veri setlerinde disk I/O yükü yaratarak darboğaz oluşturabilir.
Sql server yapısında bir veri okunduktan sonra tekrar kullanılma ihtimaline karşı okunan verinin Tempdb veritabanında tutulması işlemidir. Ekstra bir maliyet oluşmasın diye tabloya tekrardan ihtiyaç duyulma ihtimaline karşı geliştirilmiş olan bir yapıdır.
Birden fazla spool operatörü vardır. Bunlar:
- Lazy Spool
- Eager Spool
- Table Spool
- Row Count Spool
- Index Spool
Genellikle spool operatörleri okuma yapan operatörlerle birlikte kullanılmaktadır.
Spool operatörlerinin veri okuması yapan operatörlerle beraber kullanıldığını söylemiştik. Fakat SQL Server’da Execution plan operatörleri başka bir operatör vasıtasıyla veriyi okurken iki yöntem kullanabilirler. Bunlardan ilki veri kümesinde bulunan kayıtlarımızın teker teker okunup işlenmesi işlemidir. Bu şekilde çalışan operatörlere Non Blocking operatörler denmektedir. Bu operatörlere örnek olarak Nested Loop Join operatörünü verebiliriz. Çünkü bildiğiniz gibi Nested Loop Join operatörü veri kümesi üzerinde her satır için işlem yapan bir operatördür. İkinci bir veri okuma yöntemi ise veri kümesindeki verilerin teker teker değil tüm kayıtların aynı anda okunmasıdır. Bu şekilde çalışan operatörlere ise Blocking operatörleri denmektedir. En sık kullanılan Blocking operatörü ise Sort operatörüdür. Çünkü Sort yani sıralama işleminin yapılabilmesi için veri kümemizdeki kayıtların teker teker değil hepsinin beraber okunup değerlendirmesi gerekmektedir.
Şimdi execution plan üzerinde olan Eager Spool(Table Spool) operatörünü detaylı bir şekilde ele alalım:
Ayrıca yukarıdaki resimde dikkat etmemiz gereken bir diğer nokta ise Execution planımızda kullanılan Table Spool (Eager Spool) operatörünün üzerinde hem Table Spool hem de Eager Spool ifadesinin bulunmasıdır. Bunun sebebi ise her ikisi de Spool işlemi yapan Table Spool ve Eager Spool beraber kullanılabilen operatörlerdir. Çünkü Table Spool operatörü fiziksel bir operatör iken Eager Spool operatörü ise mantıksal (logical) operatördür. Fiziksel ve mantıksal operatörler arasındaki fark ise mantıksal operatörler yapılacak olan işlemi tanımlarken, fiziksel operatörler ise buna uygun olarak işlemi yapan operatörleri belirtmektedir. Yani Table Spool (Eager Spool) ile yapılacak mantıksal işlemin Eager Spool olduğunu görebiliyoruz. Eager Spool operatörü ile Nonclustered indeksimizden verinin bir defada tamamının okunacağını belirtiyoruz. Fakat verinin tamamının okunup Tempdb veritabanında bir tabloda saklanması işlemini fiziksel olarak yapan operatör ise Table Spool operatörüdür.
Eager Spool, Blocking operatör olup gerektiği durumlarda bir veri kümesindeki verilerinin tamamını bir defada okuyup sonuçlarını Tempdb veritabanında saklanmasını sağlamak için kullanılmaktadır. Eager Spool operatörünün veri kümesindeki kayıtların tamamını bir defada okuması doğrudan performansla ilgili değil veri bütünlüğü ile ilgili durumlarda da, veri bütünlüğünün sağlanması için de kullanılmaktadır.
Eager Spool bir önceki operatörden bir talep geldiğinde bütün satırları tek seferde alır ve tempb’ye atar.
Özellikle Update işlemlerinde ortaya çıkabilecek olan Halloween Probleminin engellenmesi için Blocking operatör olan Eager Spool operatörü kullanılmaktadır.
SQL Server böyle bir sorun yaşamamak için güncelleme işlemi yapmadan önce verinin tümünü Spool işlemi ile okuyarak Tempdb veritabanında tutar ve tutmuş olduğu bu kayıtlar üzerinde sıra gözetmeksizin işlem yapar. Daha önce de değindiğimiz gibi SQL Server verinin tümünü bir defadan okuyup Tempdb veritabanında saklaması için Blocking operatör olan Eager Spool işlemini kullanacaktır.
Halloween senaryosunu yaşamasının en önemli sebebi veriyi bir temp tabloya almaması ve verinin tablo üzerinde güncellendikten sonra ilgili kolun indexsli olduğu için kendi içerisinde tekrardan düzenlenir. Buda aynı kayıtların tekrar sıralanması ve en sonra değerlerin hepsinin eşit olacağını göstermektedir.

Spool her zaman “kötü” değildir, ancak bazen eksik bir index’in habercisidir:
- Tempdb Şişmesi: Spool işlemleri tempdb’de gerçekleşir. Eğer Spool operatörü milyonlarca satır işliyorsa, tempdb üzerinde ciddi bir yük ve yavaşlama oluşturur.
- Index Eksikliği: Eğer planınızda sürekli Index Spool görüyorsanız, SQL Server size şunu demek istiyordur: “Burada bir index olsaydı ben bunu kendim oluşturmak zorunda kalmazdım.” Bu durumda ilgili kolonlara kalıcı bir index eklemeyi düşünmelisiniz. Index spool makalesi okunabilir.
- Eager Spool ve Engelleme: Eager Spool, altındaki tüm veriyi okumadan üst tarafa veri göndermediği için sorgunun “ilk satırı getirme süresini” (Time to First Row) uzatabilir.
Eager Spool, altındaki tüm veriyi çekip tempdb’ye yazana kadar üst operatörlere veri göndermez. Bu, sorgunun başlangıç süresini (Time to First Row) uzatır.
- Ne Zaman Aksiyon Almalı?
- Sorgu çok yavaş başlıyorsa.
- Spool içindeki veri miktarı milyonlarca satırı buluyorsa (Tempdb darboğazı).
- Halloween Protection: SQL Server, bir veriyi güncellerken (UPDATE) aynı veriyi tekrar okuyup sonsuz döngüye girmemek için Eager Spool koyar. Eğer bu bir UPDATE sorgusunda ise genellikle normaldir.
- Eğer bir SELECT sorgusunda ve büyük veri setinde görüyorsanız, Index eksikliği veya eksik bir Join koşulu olup olmadığını kontrol edin.
Özetle Ne Yapmalısınız?
- Execution Count değerine bakın. Eğer Spool operatörü milyonlarca kez tetikleniyorsa, bu bir sorundur.
- Actual Number of Rows ile Estimated arasındaki farka bakın. İstatistikler güncel değilse SQL Server yanlışlıkla Spool kullanmaya karar vermiş olabilir. UPDATE STATISTICS komutunu deneyebilirsiniz.
- Tempdb üzerindeki PAGELATCH_IO gibi beklemeleri (waits) kontrol edin. Eğer Spool diske yazıyorsa, sistemi yavaşlatır.
Not: Row Count Spool Sadece satırların var olup olmadığını veya kaç adet olduğunu kontrol eder. Verinin kendisini değil, sadece sayısını veya varlık bilgisini saklar.
Bu makalede MSSQL Server Execution Plan Eager Spool Kavramı detaylı bir şekilde görmüş olduk.
Başka bir makalede görüşmek dileğiyle…
“Biz ona şah damarından daha yakınız.” Kaf-16
