Sizin için performans izleyicisi ve Aktivite Monitörü gördükleri tahmin edebilir SQL Compilations/sec
ve Batch Requests/sec
bir test olarak ayrı bir sorgu penceresinde bazı toplu çalışırken aşağıda ayrıntılı olarak,.
Sorgu Penceresi 1:
DECLARE @t1 datetime;
DECLARE @t2 datetime;
DECLARE @CompVal1 int;
DECLARE @CompVal2 int;
DECLARE @ReCompVal1 int;
DECLARE @ReCompVal2 int;
DECLARE @BatchVal1 int;
DECLARE @BatchVal2 int;
DECLARE @ElapsedMS decimal(10,2);
SELECT @t1 = GETDATE()
, @CompVal1 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'SQL Compilations/sec '
)
, @ReCompVal1 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'SQL Re-Compilations/sec '
)
, @BatchVal1 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'Batch Requests/sec '
);
WAITFOR DELAY '00:00:10.000';
SELECT @t2 = GETDATE()
, @CompVal2 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'SQL Compilations/sec '
)
, @ReCompVal2 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'SQL Re-Compilations/sec '
)
, @BatchVal2 = (
SELECT spi.cntr_value
FROM sys.sysperfinfo spi
WHERE spi.counter_name = 'Batch Requests/sec '
);
SET @ElapsedMS = DATEDIFF(MILLISECOND, @t1, @t2);
SELECT ElapsedTimeMS = @ElapsedMS
, [SQL Compilations/sec] = (@CompVal2 - @CompVal1) / @ElapsedMS * 1000
, [SQL Recompilations/sec] = (@ReCompVal2 - @ReCompVal1) / @ElapsedMS * 1000
, [Batch Requests/sec] = (@BatchVal2 - @BatchVal1) / @ElapsedMS * 1000;
Sorgu Penceresi 2'de, yukarıdaki kod çalışırken aşağıdakileri çalıştırın. Kod sadece 100 T-SQL toplu işlemi yürütür:
EXEC sys.sp_executesql N'SELECT TOP(1) o.name FROM sys.objects o;';
GO 100
Sorgu Penceresi 1'e geri dönerseniz aşağıdaki gibi bir şey görürsünüz:
╔═══════════════╦══════════════════════╦══════════ ══════════════╦════════════════════╗
║ ElapsedTimeMS ║ SQL Derlemeleri / sn ║ SQL Yeniden Derlemeleri / sn ║ Toplu İstekler / sn ║
╠═══════════════╬══════════════════════╬══════════ ══════════════╬════════════════════╣
10020,00 ₺ 10,07984031000 ║ 0,00000000000 ║ 10,07984031000 ║
╚═══════════════╩══════════════════════╩══════════ ══════════════╩════════════════════╝
Bu sorguya bakarsak:
SELECT dest.text
, deqs.execution_count
FROM sys.dm_exec_query_stats deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.plan_handle) dest
WHERE dest.text LIKE 'SELECT TOP(1)%'
Test sorgusunun 100 yürütme olduğunu doğrulayabiliriz.
Yukarıdaki sonuçlarda , ifadenin hersp_executesql
çalıştırılışında derlemeler aldığımızı görebilirsiniz . Bunun planı kesinlikle önbelleğe alınıyor, ancak bunun için bir derleme görüyoruz; ne oluyor?
Microsoft Dokümanlar Bu konuda söyleyecek sp_executesql
:
sp_executesql, gruplar, adların kapsamı ve veritabanı bağlamında EXECUTE ile aynı davranışa sahiptir. Sp_executesql @stmt parametresindeki Transact-SQL deyimi veya toplu iş, sp_executesql deyimi yürütülene kadar derlenmez. @Stmt içeriği daha sonra derlenir ve sp_executesql adlı toplu işin yürütme planından ayrı bir yürütme planı olarak yürütülür.
Bu nedenle, komut metni için plan zaten plan önbelleğinde olsa bile , sp_executesql
kendisi her çalıştığında derlenmektedir. @PaulWhite yanıtında sp_executesql'e yapılan çağrıların çoğunun önbelleğe alınmadığını gösterir .