SQL Server 2016 STRING_SPLIT Function

Herkese merhaba,

Bu yazımda SQL Server 2016 RC0 versiyonu ile hayatımıza giren “STRING_SPLIT” fonksiyonunu ele alacağım. Bu fonksiyon, adından da anlaşılacağı gibi parametre olarak verilen yazıyı belli bir ayraç ile ayırıp geriye tablo döndürüyor.

Aslında, neredeyse hepimiz bu işlemi ya custom function yazarak ya da CLR gibi çözümlerle yapabiliyorduk. SQL Server 2016 ile birlikte ise built-in table valued function olarak geliyor.

Esas güzellik ise bu fonksiyonun built-in gelmesinden ziyade sorgu performansına etkisi! User defined fonksiyonlar sorgu performansına ciddi anlamda kötü etki yapmaktadır.
Daha performanslı fonksiyonlar için CLR gibi çözümler olsa da hiçbiri built-in fonksiyonlar gibi olamıyor.

Küçük bir örnekle özetlemek gerekirse;

İlk önce benim yazmış olduğum fonksiyona bakalım;

CREATE FUNCTION [dbo].[fnSplitString]
(
    @string NVARCHAR(MAX),
    @delimiter CHAR(1)
)
RETURNS @output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
    DECLARE @start INT, @end INT
    SELECT @start = 1, @end = CHARINDEX(@delimiter, @string)
    WHILE @start < LEN(@string) + 1 BEGIN
        IF @end = 0
            SET @end = LEN(@string) + 1

        INSERT INTO @output (splitdata)
        VALUES (RTRIM(LTRIM(SUBSTRING(@string, @start, @end - @start))))
        SET @start = @end + 1
        SET @end = CHARINDEX(@delimiter, @string, @start)

    END
    RETURN
END
GO

Küçük bir isim listesiyle sorguyu çalıştırıyorum.

select * from dbo.fnSplitString('Ahmet, Mehmet, Kemal, Ali, Burak', ',')
GO

Screenshot_1
Görüldüğü gibi verdiğim string ifadeyi bölüp, tablo olarak çıktı alabildim.

Şimdi de SQL Server 2016 STRING_SPLIT fonksiyonu ile yapalım;

select * from STRING_SPLIT('Ahmet, Mehmet, Kemal, Ali, Burak', ',')
GO

Screenshot_2

İki fonksiyon da aynı sonucu veriyor. Şimdi de esas konu olan performansa bakalım.
Aynı parametre ile iki fonsiyonun io ve time istatistiklerini inceleyelim.

set statistics io, time off

DECLARE @String VARCHAR(8000) ;
SELECT @String = COALESCE(@String + ',','') +  name
FROM sys.all_columns;

set statistics io, time on

select * from dbo.fnSplitString(@String, ',')
GO

Screenshot_3

Benim yazmış olduğum fonksiyon 214 milisaniyede sonuç döndü. Ayrıca temp tablo oluşturduğu için de logical read yaptı.

Built-in function:

set statistics io, time off

DECLARE @String VARCHAR(8000) ;
SELECT @String = COALESCE(@String + ',','') +  name
FROM sys.all_columns;

set statistics io, time on

select * from STRING_SPLIT(@String, ',')
GO

Screenshot_4.jpg

String_Split fonksiyonu dramatik bir şekilde daha iyi sonuç verdi. 1 milisaniyede çalıştı.
Bu sonuç sorgu bazında değişebilir olsa da her zaman built-in fonksiyon daha iyi olacaktır.

Gelecek versiyonlarda bu fonksiyonun daha da geliştirilmesi bekleniyor.
Örneğin, fonksiyon numeric değerleri de string olarak geri dönüyor. Yani numeric bir alanla bu fonksiyonu join’lerseniz implicit conversion uyarısını göreceksinizdir.

Umarım faydalı bir yazı olmuştur. Anlaşılmayan yerler varsa lütfen yorum olarak bildirin.

Okuduğunuz için teşekkürler.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s