아래와 같이 성능 모니터 및 활동 모니터에 표시되는 대략적인 값을 테스트로 별도의 쿼리 창에서 일부 배치를 실행하는 동안 SQL Compilations/sec
및 Batch Requests/sec
에 대해 확인할 수 있습니다.
쿼리 창 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;
쿼리 창 2에서 위 코드가 실행되는 동안 다음을 실행하십시오. 이 코드는 단순히 100 개의 T-SQL 배치를 실행합니다.
EXEC sys.sp_executesql N'SELECT TOP(1) o.name FROM sys.objects o;';
GO 100
쿼리 창 1로 다시 전환하면 다음과 같은 내용이 표시됩니다.
╔ ================ ╦ ================================== =============== ╦ =======================
lapse ElapsedTimeMS ║ SQL 컴파일 / 초 ║ SQL 재 컴파일 / 초 ║ 배치 요청 / 초 ║
╠ ================ ╬ ================================== =============== ╬ =======================
║ 10020.00 ║ 10.07984031000 ║ 0.00000000000 ║ 10.07984031000 ║
╚ ================ ╩ ======================== ╩ ========== =============== ╩ =======================
이 쿼리를 보면 :
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)%'
테스트 쿼리가 100 번 실행되었음을 확인할 수 있습니다.
위의 결과 에서 명령문이 실행될 때마다 컴파일되고 있음을 알 수 있습니다 sp_executesql
. 이를위한 계획은 확실히 캐시되고 있지만, 우리는 그것을위한 편집을 보게됩니다. 무엇을 제공합니까?
마이크로 소프트 문서는 이에 대해 말할 sp_executesql
:
sp_executesql은 배치, 이름 범위 및 데이터베이스 컨텍스트와 관련하여 EXECUTE와 동일한 동작을 갖습니다. sp_executesql @stmt 매개 변수의 Transact-SQL 문 또는 일괄 처리는 sp_executesql 문이 실행될 때까지 컴파일되지 않습니다. 그런 다음 @stmt의 내용은 sp_executesql이라는 배치의 실행 계획과 별도로 실행 계획으로 컴파일 및 실행됩니다.
따라서 명령 텍스트에 대한 계획이 이미 계획 캐시에 있더라도 실행할 때마다 sp_executesql
자체 컴파일됩니다. @PaulWhite는 그의 대답 에서 sp_executesql에 대한 대부분의 호출이 실제로 캐시되지 않음을 보여줍니다 .