CPU 사용률이 높은 서버의 문제를 해결하고 있습니다. 쿼리가 실제로 발생하지 않았 음을 확인한 후 컴파일을 조사하기 시작했습니다.
성능 모니터에 초당 50 회 미만의 컴파일 및 초당 15 회 미만의 재 컴파일이 표시됩니다.
컴파일을 찾는 XE 세션을 실행하면 초당 수천 개의 컴파일이 표시됩니다.
이 시스템은 트리거를 사용하여 변경 사항을 감사합니다. 대부분의 컴파일은 트리거로 인한 것입니다. 트리거는 sys.dm_tran_active_transactions를 참조합니다.
첫 번째 생각은 트리거에서 DMV를 참조하면 매번 컴파일되거나이 특정 DMV만으로 인해 발생하는 것으로 생각했습니다. 그래서 저는 그 이론을 테스트하기 시작했습니다. 매번 컴파일하지만 DMV를 참조하지 않고 대신 값을 하드 코딩 할 때 트리거 될 때마다 트리거가 컴파일되는지 확인하지 않았습니다. 트리거 될 때마다 여전히 컴파일 중이었습니다. 트리거를 삭제하면 컴파일이 중지됩니다.
- XE 세션에서 sqlserver.query_pre_execution_showplan을 사용하여 컴파일을 추적합니다. 왜 그와 PerfMon 카운터 사이에 불일치가 있습니까?
- 트리거가 실행될 때마다 컴파일 이벤트가 발생하는 것이 정상입니까?
재현 스크립트 :
CREATE TABLE t1 (transaction_id int, Column2 varchar(100));
CREATE TABLE t2 (Column1 varchar(max), Column2 varchar(100));
GO
CREATE TRIGGER t2_ins
ON t2
AFTER INSERT
AS
INSERT INTO t1
SELECT (SELECT TOP 1 transaction_id FROM sys.dm_tran_active_transactions), Column2
FROM inserted;
GO
--Both of these show compilation events
INSERT INTO t2 VALUES ('row1', 'value1');
INSERT INTO t2 VALUES ('row2', 'value2');
GO
ALTER TRIGGER t2_ins
ON t2
AFTER INSERT
AS
INSERT INTO t1
SELECT 1000, Column2
FROM inserted;
GO
--Both of these show compilation events
INSERT INTO t2 VALUES ('row3', 'value3');
INSERT INTO t2 VALUES ('row4', 'value4');
DROP TRIGGER t2_ins;
--These do not show compilation events
INSERT INTO t2 VALUES ('row5', 'value5');
INSERT INTO t2 VALUES ('row6', 'value6');
DROP TABLE t1, t2;