-
- Üyelik Tarihi
- 24 Mar 2017
-
- Mesajlar
- 4,578
-
- MFC Puanı
- 1,437
SQL Serverda kullanılan en yaygın veri tiplerinden birisi de tarihsel veri tipleridir.Microsoft SQL Server 2008 ile birlikte yeni gelen tarihsel veri tipleri de dahil SQL Server 2016da hala kullanımda olan 6 adet tarihsel veri tipi (date, datetime, datetime2, smalldatetime, datetimeoffset, time) bulunmaktadır. Bu veri tiplerinden uygun olan seçilerek tarihsel veriler tutulabilmekte ve gerektiğinde sorgularda kullanılarak istenilen veriler getirilebilmektedir. Ancak çoğu zaman tarihsel veri tiplerini sorgularken kullanılan yönteme bağlı olarak sorgu performansı olumsuz etkilenebilmektedir. Bu yazımızda SQL Serverda tarihsel verileri sorgularken performans açısından dikkat etmemiz gereken noktalardan birini ele alacağız.
SQL Serverda tarih verileri üzerinde dönüşüm işlemleri bazen formatlama bazen de filtreleme gereksinimleri yüzünden çok sık yapılmaktadır. Özellikle bir tabloda datetimetipinde kullanılmış olan bir kolon varsa ve belli bir gündeki tüm verilere ihtiyaç duyuluyorsa bu durumda sık başvurulan yöntemlerden biri convert() fonksiyonunun kullanılmasıdır. Genellikle convert() fonksiyonu style 112 parametresi ile kullanılarak ilgili tarih verisinin sadece gün ay yıl bilgisi alınıp gerekli tarih verisi ile karşılaştırılır.
Yazım bakımından çok pratik olan ve sık kullanılan bu yöntem bazı durumlarda bizeperformans sorunu yaratacaktır. Bunun yerine ya cast(), convert() gibi fonksiyonları kullanmadan değeri manuel yapmamız gerekir ya da cast(), convert() gibi dönüşüm fonksiyonlarını kullanırken veri tipini doğru seçmemiz gerekir.
Konuyu bir örnek ile daha detaylı ele alalım. Aşağıdaki gibi üç kolondan oluşan bir tablo oluşturup tablodaki tarih kolonuna rastgele 500000 tarih verisini insert edelim.
Yukarıdaki kod bloğundaki gibi tablomuzu oluşturup 500000 kaydı rastgele insert ettik. Daha sonra tarih kolonu üzerinde sorgularımızda kullanmak üzere index oluşturduk.
Tablomuz hazır olduğuna göre bu aşamada ilk olarak sık kullanılan convert()fonksiyonunu 112 style parametresi ile kullanarak varchar veri tipine dönüştürerek işlem yapalım. Ardından aynı sorguyu yine cast() veya convert() fonksiyonu ile birlikte, bu sefer varchar veri tipine değil date veri tipine dönüştürelim. Sorgumuzun başında IO değerlerini karşılatırmak için set statistics io on ifadesini de eklemeyi unutmayalım.
Sorgularımız aşağıdaki gibi olacaktır:
Her iki sorguyu da çalıştırdığımızda ikisinden de aynı sonucun döndüğü görebiliyoruz. Şimdi sorgu penceremizin Messages kısmına geçerek IO değerlerini inceleyelim:
Yukarıdaki resimde de görebileceğimiz üzere ilk sorgumuz 1127 IO yaparak sorgu sonucuna erişirken ikinci yazdığımız sorgu aynı sonuca sadece 3 IO yaparak erişmiştir. Şimdi de sorgularımızın execution planlarını inceleyelim:
Execution planları yukarıdaki resimde görüldüğü gibi incelediğimizde ilk sorgu için index scan işlemi yapılırken ikinci sorgu için aynı index üzerinde index seek işlemi yapılmıştır. Bu sebeple IO değerleri arasında bu denli fazla fark oluşmaktadır. Ayrıca dikkatinizi çekmek istediğim bir başka nokta da ilk execution planda Select operatörü üzerinde birWarning yani uyarı çıkmaktadır. O uyarıyı incelediğimizde bize aşağıdaki gibi bir dönüşüm işleminin execution plan seçimine etki edeceğini belirtmektedir:
Görüldüğü üzere tarihsel veriler üzerinde cast() ve convert() gibi fonksiyonlarla dönüşüm işlemi yaparken dönüşüm yapmak istediğimiz veri tipinin doğru bir şekilde tercih edilmesi performanslı sorgu oluşturmak için hayli önemlidir.
Bu yazımızda SQL Serverda kullanılan tarihsel verileri dönüşüm fonksiyonları ile dönüştürerek karşılaştırma yaparken dikkat edilmesi gereken noktalardan biri olan hedef veri tipinin doğru belirlenmesi konusunu ele aldık. Oluşturduğumuz tablo üzerinde yapılan örnekte yazılan iki farklı sorgunun performans karşılaştırmasını gösterdik. Umarım faydalı olur.
alıntıdır
SQL Serverda tarih verileri üzerinde dönüşüm işlemleri bazen formatlama bazen de filtreleme gereksinimleri yüzünden çok sık yapılmaktadır. Özellikle bir tabloda datetimetipinde kullanılmış olan bir kolon varsa ve belli bir gündeki tüm verilere ihtiyaç duyuluyorsa bu durumda sık başvurulan yöntemlerden biri convert() fonksiyonunun kullanılmasıdır. Genellikle convert() fonksiyonu style 112 parametresi ile kullanılarak ilgili tarih verisinin sadece gün ay yıl bilgisi alınıp gerekli tarih verisi ile karşılaştırılır.
Yazım bakımından çok pratik olan ve sık kullanılan bu yöntem bazı durumlarda bizeperformans sorunu yaratacaktır. Bunun yerine ya cast(), convert() gibi fonksiyonları kullanmadan değeri manuel yapmamız gerekir ya da cast(), convert() gibi dönüşüm fonksiyonlarını kullanırken veri tipini doğru seçmemiz gerekir.
Konuyu bir örnek ile daha detaylı ele alalım. Aşağıdaki gibi üç kolondan oluşan bir tablo oluşturup tablodaki tarih kolonuna rastgele 500000 tarih verisini insert edelim.
01-- Tablomuzu oluşturalım
02create table tarihTest
03(
04id int identity primary key,
05tarih datetime,
06deger char(500) default 'Abdullah'
07)
08
09
10-- Tablomuza 500000 adet kayıt ekleyelim
11insert into tarihTest (tarih)
12select DATEADD(MI, RAND()*10000, GETDATE())
13GO 500000
14
15
16-- Tarih kolonundaki performansı incelemek için index oluşturalım
17create index ix_tarih on tarihTest (tarih)
02create table tarihTest
03(
04id int identity primary key,
05tarih datetime,
06deger char(500) default 'Abdullah'
07)
08
09
10-- Tablomuza 500000 adet kayıt ekleyelim
11insert into tarihTest (tarih)
12select DATEADD(MI, RAND()*10000, GETDATE())
13GO 500000
14
15
16-- Tarih kolonundaki performansı incelemek için index oluşturalım
17create index ix_tarih on tarihTest (tarih)
Yukarıdaki kod bloğundaki gibi tablomuzu oluşturup 500000 kaydı rastgele insert ettik. Daha sonra tarih kolonu üzerinde sorgularımızda kullanmak üzere index oluşturduk.
Tablomuz hazır olduğuna göre bu aşamada ilk olarak sık kullanılan convert()fonksiyonunu 112 style parametresi ile kullanarak varchar veri tipine dönüştürerek işlem yapalım. Ardından aynı sorguyu yine cast() veya convert() fonksiyonu ile birlikte, bu sefer varchar veri tipine değil date veri tipine dönüştürelim. Sorgumuzun başında IO değerlerini karşılatırmak için set statistics io on ifadesini de eklemeyi unutmayalım.
Sorgularımız aşağıdaki gibi olacaktır:
Her iki sorguyu da çalıştırdığımızda ikisinden de aynı sonucun döndüğü görebiliyoruz. Şimdi sorgu penceremizin Messages kısmına geçerek IO değerlerini inceleyelim:

Yukarıdaki resimde de görebileceğimiz üzere ilk sorgumuz 1127 IO yaparak sorgu sonucuna erişirken ikinci yazdığımız sorgu aynı sonuca sadece 3 IO yaparak erişmiştir. Şimdi de sorgularımızın execution planlarını inceleyelim:

Execution planları yukarıdaki resimde görüldüğü gibi incelediğimizde ilk sorgu için index scan işlemi yapılırken ikinci sorgu için aynı index üzerinde index seek işlemi yapılmıştır. Bu sebeple IO değerleri arasında bu denli fazla fark oluşmaktadır. Ayrıca dikkatinizi çekmek istediğim bir başka nokta da ilk execution planda Select operatörü üzerinde birWarning yani uyarı çıkmaktadır. O uyarıyı incelediğimizde bize aşağıdaki gibi bir dönüşüm işleminin execution plan seçimine etki edeceğini belirtmektedir:

Görüldüğü üzere tarihsel veriler üzerinde cast() ve convert() gibi fonksiyonlarla dönüşüm işlemi yaparken dönüşüm yapmak istediğimiz veri tipinin doğru bir şekilde tercih edilmesi performanslı sorgu oluşturmak için hayli önemlidir.
Bu yazımızda SQL Serverda kullanılan tarihsel verileri dönüşüm fonksiyonları ile dönüştürerek karşılaştırma yaparken dikkat edilmesi gereken noktalardan biri olan hedef veri tipinin doğru belirlenmesi konusunu ele aldık. Oluşturduğumuz tablo üzerinde yapılan örnekte yazılan iki farklı sorgunun performans karşılaştırmasını gösterdik. Umarım faydalı olur.
alıntıdır