SQL Server Performance – Tarih Dönüştürme İşlemleri

SQL Server‘da 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 2016‘da 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 Server’da tarihsel verileri sorgularken performans açısından dikkat etmemiz gereken noktalardan birini ele alacağız.

SQL Server’da 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 datetime tipinde 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 bize performans 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.

-- Tablomuzu oluşturalım
create table tarihTest
(
id int identity primary key,
tarih datetime,
deger char(500) default 'Abdullah'
)


-- Tablomuza 500000 adet kayıt ekleyelim
insert into tarihTest (tarih)
select DATEADD(MI, RAND()*10000, GETDATE())
GO 500000


-- Tarih kolonundaki performansı incelemek için index oluşturalım
create 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:


set statistics io on;

declare @sdate datetime = '2016-06-16 11:19:39.530'

select tarih from tarihTest
where CONVERT(varchar, tarih, 112) = CONVERT(varchar, @sdate, 112)

select tarih from tarihTest
where CAST(tarih as date) = CAST(@sdate as date)

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:

tarihsonuc1

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:

tarihsonuc2

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 bir Warning 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:

tarihsonuc3

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 Server‘da 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.

Bir sonraki yazımızda görüşmek dileğiyle. Keyifli okumalar…

Yazar: Abdullah ALTINTAŞ

SQL Server Performance – Tarih Dönüştürme İşlemleri” üzerine bir düşünce

  1. hocam teşekkürler emeğinize sağlık çok faydalı bi paylaşım oldu
    devamını beklyoruz en kısa zmanda teşekkürler

Yorum Yaz