Selam millet,
Bir ortamımda SQL Server 2008 R2 Instance'ı ve uyumluluk açısından da SQL Server Management Studio (SSMS)'nun ilgili versiyonu kullanılıyor.
Bu ortamdaki bir Index'i Covered Index yaparken hatırıma geldi, sizlerle de paylaşayım dedim. Seneler önce bir gün, çok yoğun Transaction olan bir ortamda çalışırken, yine bir Index'i değiştirirken büyük bir hata yapmıştım. SSMS bazen bu tür hataları yapmanıza çok yardımcı olabiliyor, konunun başlığı da buradan geliyor zaten.
Index'i Covered Index yapmak için SSMS'ten Index'in özelliklerine gittim, Included Columns bölümünden eklemek istediğim alanı ekledim ve sonra Script düğmesine tıklayıp Script'ini aldım ve sonuç aşağıdaki gibi oldu (tabii ki özel bilgileri gizledim):
*********************************
USE []
GO
DROP INDEX [] WITH ( ONLINE = OFF )
GO
USE []
GO
CREATE NONCLUSTERED INDEX [] ON [dbo].[]
(
[alan_adı1] ASC,
[alan_adı2] ASC,
…
)
INCLUDE ( [alan_adı3],
[alan_adı4]) WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
*********************************
Özellikle yoğun ortamlar için bu çok tehlikeli bir kod örneği. Ben vaktinde bu hatayı yaptım, yine yoğun ortamlarda çalışan arkadaşlarım yapmasın. Eğer bu kodu çok yoğun Transaction'ların olduğu bir ortamda çalıştırırsanız, önce tablonuzu Index'siz bırakmış oluyorsunuz, ardından çok yoğun Blocking'ler oluşabiliyor, Index, IO ve tabii Cache masraflarınız dehşet şekilde artabiliyor ve bu yoğunlukta yeni Index'i öyle çabucak oluşturamıyorsunuz. Yığılan işlemlerin tamamlanmasını beklemek zorunda kalıyorsunuz. O gün nasıl kızardığımı ve zor durumda kaldığımı unutamam.
Tabii ki SSMS'i geliştirenler, kendilerini de zamanla geliştiriyorlar belli ki. Örneğin SQL Server 2014'ün SSMS'inde aynı tablo için aynı Included Column'ı eklediğinized ve Script'ini oluşturduğunuzda aşağıdaki gibi, yani olması gerektiği gibi bir kod oluşuyor:
*********************************
USE []
GO
CREATE NONCLUSTERED INDEX [] ON [dbo].[]
(
[alan_adı1] ASC,
[alan_adı2] ASC,
…
)
INCLUDE ( [alan_adı3],
[alan_adı4]) WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = ON, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
*********************************
Eğer Enterprise Edition kullanıyorsanız ONLINE parametresini de ON yapmalısınız. Eğer TempDB veritabanınız performanslı bir diskte ise, SORT_IN_TEMPDB parametresini de ON yapmalısınız. Böylece kritik Production veritabanınızda bu Index işlemiyle oluşacak olan yükü en aza indirgemiş olursunuz. Bununla birlikte, daha daha performans için Index'leri farklı bir diskteki farklı bir FileGroup'ta da tutabilirsiniz.
Peki DROP_EXISTING'in nasıl bu kadar büyük bir fark yaratabiliyor? Arkadaşım Turgay Sahtiyan zaten bu konuda bir makale yazmış, ben de aynı şeyleri tekrar yazmayayım.
SSMS'in azizlikleri sadece bununla kalmıyor. Hangi versiyondu çok çok emin değilim, ama muhtemelen SQL Server 2005'in SSMS'iydi, bir veritabanının özelliklerinde, bir dosyanın özelliklerini değiştirdiğinizde Shrink işlemi de yapıyordu. Bunu, o işlemi arayüzde yapmayıp Script'ini çıkarttığınızda görebiliyordunuz.
Yine başka bir Bug, ki bu son versiyonlarda da vardı, örneğin Log Shipping kurarken siz zaman olarak örneğin Log dosyalarımı sadece 3 gün tut olarak seçiyorsunuz arayüzde, fakat sonra aynı ekranı açtığınızda bir bakıyorsunuz 3 saat olarak kaydetmiş… Bu konuda bir makalem de vardı da, bulamadım.
Örneğin hala piyasadaki birçok yazılımcı, çok deneyimliler bile, bir tabloya bir alan ekleyecekleri zaman SSMS'teki Designer'ı kullanıyorlar. Bazı işlemlerde SSMS ilgili tabloyu tamamen siliyor ve tekrar oluşturuyor. Böyle bir şeyin Production ortamınızda olmasını gerçekten ister misiniz?
Bu yazımdan anlamanızı istediğim şey, işlemleri SSMS arayüzünden yaptıktan sonra hemen OK düğmesine basıp çalıştırmayın. Özellikle de kritik ortamlarda bunu sakın yapmayın. SSMS'in her versiyonda davranış değişiklikleri olabileceğinin bilincinde olun. Yapacağınız işlemin önce Script'ini çıkartın, mümkünse doğrudan ve sadece Script'i çalıştırın. T-SQL öğrenin, mümkün olan her yerde T-SQL ile çalışmayı alışkanlık haline getirin. Elbette Extended Event oluştururken arayüz kullanın veya benzer pratik durumlarda, fakat kritik işlemler için tetikte olmakta fayda var.
Kolay gelsin,
Ekrem Önsoy