sp_executesql ve EXEC Kullanımı

Dinamik Query lerimizi EXEC ile mi sp_executeSql ile mi Çağırmalıyız ?

Firmalarda bir çok kod incelememde karşılaştığım en önemli performans kriterlerinden ve en çok karşılaşılan türden bir performans problemidir.

Elimizde bir dinamik sorgumuz var ve bu sorgumuzu EXEC … diye mi yoksa sp_execute … diye mi çalıştırmak daha sağlıklı sorusunun cevabını aşağıda yapacağımız demo ile uygulamalı olarak sizlere anlatıyor olacağım.

Normal şartlar altında bir SQL Query mizi doğrudan çalıştırdığımızda , bellekteki en uygun query plan ı okuyarak ona göre sorguyu çalıştırır.  Dinamik Query lerimizde bu süreç bu şekilde gelişmemekte ve her çalıştırılmada tekrar tekrar Execution Plan oluşturulur her çalıştırılmada. Peki bu bize canlı sistemlerimizde nasış bir yük oluşturuyor derseniz bunu daha derin bir makale de sizlere detaya girerek aktaracağım ama Execution her oluşturulurken CPU ya yük bindirecek ve sistem Source larını yüklü miktarda kullanıma göre tüketerek canlı sistemlerinizde büyük sıkıntılara yol açabilir.

Sp_executesql parametrik olabilirken EXECUTE (EXEC) komutu parametrik değildir.  Yani hazırlanan query nin parametrik olmasından bahsediyoruz.

Performans açısından ise sp_executesql ile çalıştırılan query ler ‘in execution planı memory de tutulduğundan parametre değişse de aynı execiton planı kullanmaktadır. Diğer yöntem ile çağrılan her query her defasında yeni bir Execution plan oluşturmaktadır.

 

Şimdi sizlere bu anlatımın Demosunu gerçekleştirelim.

CREATE TABLE Personel_TT
(
Personel_Id INT IDENTITY (1,1) PRIMARY KEY CLUSTERED ,
Identity_Number CHAR(11) NOT NULL,
First_Name VARCHAR(100),
Last_Name VARCHAR(100),
Phone VARCHAR(12) NOT NULL,
Email VARCHAR(100) NOT NULL,
Gender VARCHAR(1)  NOT NULL);


-- Kayıt Ekleme
INSERT INTO Personel_TT
(
Identity_Number,
First_Name,
Last_Name,
Phone,
Email,
Gender
)
VALUES 
(
'12345678910',
'Yusuf',
'Kahveci',
'05309999999',
'[email protected]',
'E'
)
GO

INSERT INTO Personel_TT
(
Identity_Number,
First_Name,
Last_Name,
Phone,
Email,
Gender
)
VALUES 
(
'98765432101',
'Adam',
'Exev',
'05409999999',
'[email protected]',
'E'
)
GO

INSERT INTO Personel_TT
(
Identity_Number,
First_Name,
Last_Name,
Phone,
Email,
Gender
)
VALUES 
(
'65432896471',
'Marry',
'Chunk',
'05407777777',
'[email protected]',
'B'
)

GO

Yukarıda demo tablomuzu oluşturup içerisine datamızı basıyoruz. Daha sonra yapımızda ki Cache i aşağıda ki Script ile temizliyoruz.

-- Cachi Temizleme Scriptim
DBCC FREEPROCCACHE
 GO

Daha sonra ise EXEC ile sp_executesql örneğimizi hazırladığımız scriptimizi RUN ediyoruz.

DECLARE @Identity_Number CHAR(11);
DECLARE @Query NVARCHAR(200);
 
SET @Query = 'SELECT * FROM Personel_TT WHERE Identity_Number = ';
 
SET @Identity_Number = '12345678910';
EXEC( @Query + @Identity_Number);
 
SET @Identity_Number = '98765432101';
EXEC( @Query + @Identity_Number);

SET @Identity_Number = '65432896471';
EXEC( @Query + @Identity_Number);
 
 
SET @Query = 'SELECT * FROM Personel_TT WHERE Identity_Number = @Identity_Number_parametrik';
 
SET @Identity_Number = '12345678910';
EXEC sp_executesql @Query, N'@Identity_Number_parametrik CHAR(11)',
    @Identity_Number_parametrik = @Identity_Number;
 
SET @Identity_Number = '98765432101';
EXEC sp_executesql @Query, N'@Identity_Number_parametrik CHAR(11)',
    @Identity_Number_parametrik = @Identity_Number;

SET @Identity_Number = '65432896471';
EXEC sp_executesql @Query, N'@Identity_Number_parametrik CHAR(11)',
    @Identity_Number_parametrik = @Identity_Number;

Daha sonra Cache imizi aşağıda ki script ile kontrol ettiğimizde ki sonuca baktığımızda;

SELECT  usecounts [Çağrılma Sayısı] ,
        sql Sorgu
FROM    sys.syscacheobjects;

sp_execute sql aynı plan cache i kullanmış ve 3 kere aynı plan üzerinden çalıştırılmıştır. Diğer EXEC ifadeleri ise her çağrılışında ayrı bir Plan oluşturup oradan çalıştırılmıştır.

Performans açısından sistemlerinizde yer alan  EXEC ifadelerinizin yerine sp_executesql ifadesi kullanarak performans arttırımı sağlayabilrisiniz.

İyi Çalışmalar.

Leave a Reply

Your email address will not be published. Required fields are marked *