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
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
İ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
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
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.