Özellikle Veri Ambarı (data warehouse) projelerinde büyük tablolarla çalışmak zorunda kalıyoruz. Hatta her gece TRUNCATE edip yeniden doldurduğumuz tablolar da olabiliyor. Bu işlemlerde performans için dikkat edilmesi deneyimlerimi paylaşmak istiyorum.
1. TRUNCATE edilip yeniden oluşturulacak tabloya INSERT işlemi yapmadan önce tablo üzerindeki index’leri DROP etmekte fayda var. Tablo doldurulduktan sonra index’ler yeniden oluşturulur. Tablo üzerinde index bulunduğu sürece yükleme esnasında sunucu sürekli tabloyu yeniden sıralamak, indexlerin kurallarını (re-ordering/paging) uygulamak zorunda kalacaktır. Oysa tablo üzerinde index olmazsa sunucu bu konuda bir zorunluluğa girmeyip sadece ekleyerek ilerleyecektir. Tabi tablo üzerinde sadece 1 index tanımlıysa ve data import edilirken sıralı ise indexi DROP etmek çok zaman kazandırmayabilir. Bazı kaynaklarda tablo boş olduğu zaman index’lerin olmasının sorun olmayacağı yazılmış olsa da ben kişisel olarak indexlerin DROP Veya DISABLE edilmesi taraftarayım.
2. INSERT işlemi esnasında fact table başka bir tabloyla JOIN ediliyorsa anahtar alanların aynı veri türüne ve uzunluğuna sahip olması aynı index yapısında olması kolaylık sağlayacaktır.
3. Tüm sorguların çalıştırılmadan önce Execution Plan’larına mutlaka bakılması yönlendirme sağlayabilir.
4. Database üzerindeki data file ve log file’lerın farklı fiziksel disk üzerinde olması önemli performans sağlayacaktır.
5. Database’e ait recovery model’in Bulk-Logged olarak seçilmesi transacation log’ları azaltacağı için INSERT işleminin daha erken bitmesini sağlayacaktır. Çünkü bu seçenekte Full Recovery’den farklı olarak tüm insert satırlatı kaydedilmez ancak ilgili extent bilgileri kaydedilir. Aslında kaynak sistem olmayan ve veri kaybolduğunda kaynak sistemlerden yükleme yapılacak veri ambarı gibi sistemlerin Simple Recovery modunda olması daha doğru olacaktır. Bununla birlikte eğer veritabanında Full Recovery kullanmak zorundaysak ancak BULK işlemlerinin az log tutmasını istiyorsak o esnada bu modu değiştirebiliriz, aşağıdaki gibi “SELECT INTO/BULKCOPY” seçeneğini TRUE olarak set edebiliriz.
sp_dboption , 'SELECT INTO/BULKCOPY', TRUE
Böylece sistem BULK INSERT esnasında daha az log bilgisi üreteceği için zaman kazanmış olacağız.
6. Data dosyalarını SQL Server’e aktarırken DTS, SSIS veya BCP yerine BULK INSERT komutunu kullanmak tavsiye edilir. Ancak bu komut diğer komutlar gibi SQL Server’den veri dosyasına aktarım yapamaz.
7. Kaynak tablo üzerinde index yoksa ORDER BY kullanmamak daha doğru olacaktır. Ancak hedef tablo üzerinde clustered index o kolona aktarım yaparken ORDER BY kullanmak hız kazandırabilir.
8. Eğer katşı tabloyu TRUNCATE edip yeniden doldurmuyorsak ve kullanıcılar hala üzerinde çalışmaya devam edecekse biz de o tabloyu güncellemek zorunda kalacaksak tabloyu toplu güncellemek tabloyu kilitleyeceği için tabloyu parça parça güncellemek kullanıcılarının çalışmalarını olumsuz yönde çok etkilemeyecektir. Örneğin 100’er 100’er satır güncellenebilir. bunun için güncelleme cursor içerisine alınarak her güncelleme sonrası kısa süre sistemi serbest bırakıp beklemek olabilir (WAITFOR DELAY ’00:00:20′) veya SET ROWCOUNT 10000 veya “UPDATE TOP ( 10000 ) Tablo Adı” şeklinde etkilenecek kayıt sayısı belirtilebilir. Tabi bu arada sonraki güncellemelerde en son hangi satırda kaldığını sistemin biliyor olması gerekir. Bunun için de tarih kolonu veya IDENTITY alanı kullanılabilir.