Cursor Yapısını Set Tabanlı Insert Yapısına Dönüştürme

Cursor Yapısını Set Tabanlı Insert Yapısına Dönüştürme Müşterimizle yakın zamanda yaptığımız Kapsamlı Veritabanı Performansı Durum Denetimi sırasında, ekleme işlemleri için Cursor kullanımıyla ilgili, sunucunun genel performansı üzerinde zararlı bir etkisi olan önemli bir sorunla karşılaştık. İmleçler, belirli durumlarda yararlı olmakla birlikte, özellikle büyük sonuç kümeleriyle uğraşırken yavaş ve kaynak yoğun olabilir. Sonuç olarak, performansı iyileştirmek…

July 9, 2023 by Aryasoft IT

Cursor Yapısını Set Tabanlı Insert Yapısına Dönüştürme

Müşterimizle yakın zamanda yaptığımız Kapsamlı Veritabanı Performansı Durum Denetimi sırasında, ekleme işlemleri için Cursor kullanımıyla ilgili, sunucunun genel performansı üzerinde zararlı bir etkisi olan önemli bir sorunla karşılaştık. İmleçler, belirli durumlarda yararlı olmakla birlikte, özellikle büyük sonuç kümeleriyle uğraşırken yavaş ve kaynak yoğun olabilir. Sonuç olarak, performansı iyileştirmek için alternatif yaklaşımları keşfetmek önemlidir. Bu blog gönderisinde, Cursor tabanlı eklemeler konusuna odaklanacağız ve bunların küme tabanlı işlemlere nasıl dönüştürüleceğini göstereceğiz.

Örnek Kurulum

İlk olarak, bir örnek tablo oluşturacağız ve onu bazı verilerle dolduracağız. Aşağıdaki script, üç sütunlu Çalışan adlı bir tablo oluşturur: EmployeeID, FirstName, and LastName.

 

CREATE TABLE Employee (

EmployeeID INT,

FirstName VARCHAR(50),

LastName VARCHAR(50)

);

GO

INSERT INTO Employee VALUES (1, ‘John’, ‘Doe’);

INSERT INTO Employee VALUES (2, ‘Jane’, ‘Doe’);

INSERT INTO Employee VALUES (3, ‘Bob’, ‘Smith’);

INSERT INTO Employee VALUES (4, ‘Alice’, ‘Jones’);

GO

CREATE TABLE EmployeeCopy (

EmployeeID INT,

FirstName VARCHAR(50),

LastName VARCHAR(50)

);

Cursor Tabanlı Ekleme

Ardından, Çalışan tablosunda yinelenen ve her satırda bir ekleme işlemi gerçekleştiren bir Cursor oluşturacağız. Aşağıdaki komut dosyası bunun nasıl yapılacağını gösterir:

Bu Cursor, Çalışan tablosunda yinelenir ve her satır için EmployeeID, FirstName, and LastName sütunlarını alır. Ardından, Çalışan tablosunun bir kopyası olan EmployeeCopy tablosunda bir ekleme işlemi gerçekleştirir. Bu komut dosyası çalıştırılmadan önce EmployeeCopy tablosunun oluşturulması gerektiğini unutmayın.

 

DECLARE @EmployeeID INT;

DECLARE @FirstName VARCHAR(50);

DECLARE @LastName VARCHAR(50);

DECLARE EmployeeCursor CURSOR FOR

SELECT EmployeeID, FirstName, LastName

FROM Employee;

OPEN EmployeeCursor;

FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @FirstName, @LastName;

WHILE @@FETCH_STATUS = 0

BEGIN

INSERT INTO EmployeeCopy (EmployeeID, FirstName, LastName)

VALUES (@EmployeeID, @FirstName, @LastName);

FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @FirstName, @LastName;

END

CLOSE EmployeeCursor;

DEALLOCATE EmployeeCursor;

 

Set tabanlı Ekleme

Şimdi, Cursor tabanlı eklemeyi set tabanlı eklemeye dönüştürelim. Aşağıdaki komut dosyası bunun nasıl yapılacağını gösterir:

INSERT INTO EmployeeCopy (EmployeeID, FirstName, LastName)

SELECT EmployeeID, FirstName, LastName

FROM Employee;

 

Bu script, Çalışan tablosundan EmployeeID, FirstName, and LastName sütunlarını alan ve bunları EmployeeCopy tablosuna ekleyen bir seçme ifadesi gerçekleştirir. Bu yaklaşım küme tabanlıdır, yani her seferinde bir satır yinelemek yerine sonuç kümesinin tamamı üzerinde aynı anda çalışır.

Performans karşılaştırması

Son olarak, Cursor tabanlı ekleme ile küme tabanlı eklemenin performansını karşılaştıralım. Her yaklaşımın yürütme süresini ölçmek için aşağıdaki betiği kullanabiliriz:

 

DECLARE @StartTime DATETIME;

DECLARE @EndTime DATETIME;

DECLARE @Duration INT;

SET @StartTime = GETDATE();

— …

— Cursor-based insert

— …

SET @EndTime = GETDATE();

SET @Duration = DATEDIFF(MILLISECOND, @StartTime, @EndTime);

PRINT ‘Cursor-based insert duration: ‘ + CAST(@Duration AS VARCHAR(10)) + ‘ms’;

SET @StartTime = GETDATE();

— …

— Setbased insert

— …

SET @EndTime = GETDATE();

SET @Duration = DATEDIFF(MILLISECOND, @StartTime, @EndTime);

PRINT ‘Set-based insert duration: ‘ + CAST(@Duration AS VARCHAR(10)) + ‘ms’;

 

Bu script, Cursor tabanlı eklemenin ve küme tabanlı eklemenin yürütme süresini ölçer ve sonuçları konsola yazdırır. Yürütme süresini ölçmek için Cursor tabanlı ekleme kodunun açıklamasını kaldırmanız gerektiğini unutmayın.

Bu betiği çalıştırdığımızda aşağıdaki çıktıyı alıyoruz:

 

Cursor-based insert duration: 22ms

Set-based insert duration: 0ms

 

Gördüğünüz gibi, küme tabanlı ekleme işlemi Cursor tabanlı ekleme işleminden çok daha hızlıdır ve Cursor tabanlı ekleme için 18 ms ile karşılaştırıldığında yalnızca 0 ms sürer. Bunun nedeni, küme tabanlı eklemenin sonuç kümesinin tamamında aynı anda çalışması, Cursor tabanlı eklemenin ise sonuç kümesinde her seferinde bir satır yineleme yapmasıdır; bu, yavaş ve kaynak yoğun olabilir.

Çözüm

Bu blog gönderimizde, SQL Server’da bir imlecin küme tabanlı bir ekleme işlemine nasıl dönüştürüleceğini gösterdik. Örnek bir tablo oluşturduk, onu bazı verilerle doldurduk ve ardından veriler arasında yinelenen ve her satırda bir ekleme işlemi gerçekleştiren bir Cursor oluşturduk. Daha sonra imleci küme tabanlı bir ekleme işlemine dönüştürdük ve iki yaklaşımın performansını karşılaştırdık. Küme tabanlı ekleme işleminin Cursor tabanlı ekleme işleminden çok daha hızlı ve verimli olduğunu bulduk ve SQL Server’da küme tabanlı işlemleri kullanmanın faydalarını vurgulamış olduk.

Size ve Veritabanlarınıza Yardımcı Olmak İçin Bekliyoruz!