Stiamo risolvendo un problema con un server che ha un elevato utilizzo della CPU. Dopo aver scoperto che le query non lo stavano davvero causando, abbiamo iniziato a esaminare le compilation.
Performance Monitor mostra meno di 50 compilazioni / sec e meno di 15 ricompilazioni / sec.
Dopo aver eseguito una sessione XE in cerca di compilation, stiamo vedendo migliaia di compilation al secondo.
Questo sistema utilizza i trigger per controllare le modifiche. La maggior parte delle compilation sono dovute a trigger. Il trigger fa riferimento a sys.dm_tran_active_transactions.
Il nostro primo pensiero era che forse fare riferimento a un DMV in un trigger avrebbe causato la sua compilazione ogni volta, o forse solo questo DMV specifico lo avrebbe causato. Quindi ho iniziato a provare questa teoria. Viene compilato ogni volta, ma non avevo verificato se un trigger viene compilato ogni volta che viene attivato quando non fa riferimento al DMV e codifica invece un valore. Si stava ancora compilando ogni volta che veniva attivato. Rilasciando il trigger si interrompe la compilazione.
- Stiamo usando sqlserver.query_pre_execution_showplan in una sessione XE per tenere traccia delle compilazioni. Perché c'è una discrepanza tra questo e il contatore PerfMon?
- È normale ricevere un evento di compilazione ogni volta che viene eseguito un trigger?
Script di riproduzione:
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;