Implicit Conversion nedir? #QueryOptimization

Implicit Conversion yine execution planlarda sık karşılaşılan ancak genelde umursanmayan ya da performansa olan etkisi bilinmeyen bir uyarıdır.

Ne zaman oluşur?

Tip dönüşümleri yapıldığında ya da SQL Engine’in tip dönüşümü yapmaya zorlandığı durumlarda ortaya çıkar. Karşılaşmak istemediğimiz, kolay çözülebilen ancak frequency query’lerde olduğu zaman SQL Server’ın CPU’suna büyük yük getirebilecek bir uyarıdır kendileri.

StackOverFlow veritabanı üzerinde Badges tablosunda örneğimi yapacağım.

İşte tablo tasarımı;

Image for post

Şöyle bir örnek ile başlayalım ;

SET STATISTICS IO,TIME ON
DECLARE @Name_VARCHAR VARCHAR(100) = 'Teacher'SELECT Name FROM [dbo].[Badges_VARCHAR] WHERE Name = @Name_VARCHAR

Alanımın tipi zaten VARCHAR olduğundan 101241 satır getirmek için IX_Name adındaki oluşturmuş olduğum index’e SEEK yaptı.

  • Okunan page sayısı : 319
  • Execute süresi : 566ms
  • CPU tüketimi : 31ms
Image for post
Image for post
DECLARE @Name_NVARCHAR NVARCHAR(100) = N'Teacher'SELECT Name FROM [dbo].[Badges_VARCHAR] WHERE Name = @Name_NVARCHAR

Değişkenimi NVARCHAR olarak değiştirip tip uyuşmazlığına yol açtığımda, 101241 satır getirmek için IX_Name index’ine SCAN işlemi yapmayı tercih ediyor ve bu sebeple değerlerimiz artıyor.

Ayrıca bir warning var. SQL Engine’in conversion işleminden dolayı plan seçiminin etkilenebileceğini söylüyor.

Evet. Tebrikler SQL doğru bildin.

  • Okunan page sayısı : 3752
  • Execute süresi : 718ms
  • CPU tüketimi : 188ms
Image for post
Image for post
Image for post

Bu örnekte yanlış plan seçimi yapan bir sorguyla conversion işlemine baktık. Bir de planı değişmeyen bir sorguyla devam edelim.

DECLARE @UserId_INT INT =3718SELECT UserId FROM Badges WHERE UserId = @UserId_INTDECLARE @UserId_VARCHAR VARCHAR(100) = '3718'SELECT UserId FROM Badges WHERE UserId = @UserId_VARCHAR
Image for post
Image for post

İki sorgumuzda da aynı index’i seek yaptı, okuma değerlerimiz değişmedi. Sadece conversion’ın olduğu sorguda ufak bir warning var.

SQL Server’ı biraz zorlayalım o halde.

SQLQueryStress kullanarak bir test yapıyorum. Her sorguyu 10 koldan gönderiyorum. Okunan page değerlerinde bir değişiklik olmamasına rağmen CPU tüketimi ve sorgu sürelerinin uzamış olduğunu gözlemliyorum.

  • CPU tüketimi : 0.0015 > 0.0037
  • Execute süresi : 07.6405 > 09.2813

Not : Query’ler çalıştırılmadan önce plan belleği temizlenmiştir.

Image for post
Image for post

Küçük farklar gibi gözükse de canlı ortamlarda ve başta dediğim gibi frequency yüksek olan sorgularda acı verebilecek bir problem. Tecrübelerim kadarıyla genelde varchar kolonlara nvarchar değişken gönderim örneği daha fazla yaşanıyor, ve yine genelde bu sorgular linq vb. tarafından üretilen sorgularda oluyor.

Ve microsoft’ta da bulabileceğin conversion tablosu;

Image for post

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.