Merhaba Sevgili Okurlar,
Bu yazımda SQL sorgu performansımızı artıran yazı dizisine bir yenisini daha ekliyorum. SQL sorgularımızda Cursor ,While ve Bulk Insert kullanımını görüp karşılaştırması yapacağız.
Okurken ne dinlemeli ?
Senaryomuzda süper kahramanlar veri tabanımız ve detaylarının güncellenmesi,yeni kahramanların kaydedilmesi gibi düşünebiliriz.Bunun için SQL update ,insert komutları gerekli olacak.Döngüyü Cursor ile While sağlayıp ya da aynı iş Bulk olarak gerçekleştireceğiz.
İlk olarak Cursor ile başlayalım :
Bir cursor tanımlayıp SELECT ile istediğimiz tabloyu cursor'e tanımlıyoruz ve FETCH ... INTO komutu ile satır satır tabloyu dolaşıyoruz.
Son olarak Close ve Deallocate ile Cursoru kapatıp bellekteki alanını serbset bırakıyoruz.
While ile örneğimize devam edelim:
While 'da ise temp table oluşturuyoruz döngüye sokmak istediğimiz tablonunun tüm kolonlarına ihtiyacımız yoksa ve fazlaca property 'si olan bir tablo ise böyle yapmak faydalı olabilir.Temp tablomuza ID tanımlıyoruz ve Bu ID yi hızlı olması için Identity ve PK tanımlıyoruz. Ayrıca döngüde artıracağımız MyCount değişkenini de kontrol etmek için gerekli olacak.
Son olarak aynı işlevi görebilen fakat döngü içermeyen bir yöntem deneyeceğiz Bulk Insert Koşullara göre eşleştirdiğimiz tabloları update ve insert edeceğiz. Daha önce koşullara uyan veriyi ilk olarak çekip içinde dönerek insert ya da update işlemini gerçekleştirdik fakat bu aşamada update ya da insert esnasında koşul sağlama işlemini gerçekleştireceğiz.Elbette bu durumda bazı sorunlar da ortaya çıkacak.İlk olarak yanlış senaryo ile başlayalım.
Kullandığımız döngülere göre sorgu süresinin çok çok azaldığını göreceğiz fakat bu sql sorusunda BEGIN TRAN ve COMMIT TRAN komutlarının arasında oldukça fazla sorgu olduğunu düşünelim. Bulk insertler işi bitene kadar tabloyu full kilitleyeceği için araya başka SQL komutlarının girmesine izin vermeyecekler. Ör: Yukarıdaki sorgumuzun bir rapor sorgusu olduğunu düşünürsek rapor çalıştığı esnada bu sorgudaki tüm tablolar kilitlenecek araya başka transaction almayacaktır. Öyleyse BEGIN TRAN ve COMMIT TRAN komutlarının arasını kısa tutmak gerektiği sonucu ortaya çıkıyor.
Araya işlem alabilen uzun SQL lock 'a sebep olmayan sorgu aşağıdaki gibi olmalı.
Görüldüğü gibi bu sorguda BEGIN TRAN ve COMMIT TRAN komutları aralara serpiştirilmiş boylece uzun kilitlere sebep olmuyor fakat Unit of Work olarak düşündüğümüzde birbiri ile ilişkili işlemlerimiz de olabilir örneğin update sonrası insert olmalı update 'de hata olursa insert olmasın gibi istekler olabilir işte bu durumda ya Unit Of Work 'e öncelik vermeliyiz ya da Araya transaction alıp almayacağımıza öncelik vermeliyiz. İsteklere göre değişen bir yapı.
Yaptığım işlemlerde en performanslı çalışan sorgunun Bulk insert olduğunu gördüm.While ve Cursor uzun işlemlerde 50dk ~40 dk sürerken Bulk insert'in 2 dk sürdüğünü gözlemledim. Cursor ve While karşılaştırmasında ise kazanan While oldu. Elbette performans yaptığımız işlere ve isteklere göre değişebilir.
Hoşça kalın, sağlıkla kalın.
Hocam iyi günler iletişim bilginize ulaşamadım, geolocation vb. Bi sorunum var yardımızı alabilir miyim? fb.com/madlover68 veya madlover68@gmail.com ulaşırsanız çok sevinirim.
YanıtlaSilsema@semakudu.com
Sil