Nous dépannons un serveur qui a une utilisation élevée du processeur. Après avoir découvert que les requêtes ne provoquaient pas vraiment cela, nous avons commencé à chercher des compilations.
L'analyseur de performances affiche moins de 50 compilations / s et moins de 15 recompilations / s.
Après avoir exécuté une session XE à la recherche de compilations, nous voyons des milliers de compilations par seconde.
Ce système utilise des déclencheurs pour auditer les modifications. La plupart des compilations sont dues à des déclencheurs. Les déclencheurs font référence à sys.dm_tran_active_transactions.
Notre première pensée était que le fait de référencer un DMV dans un déclencheur le ferait compiler à chaque fois, ou peut-être que ce DMV spécifique le provoquerait. J'ai donc commencé à tester cette théorie. Il se compile à chaque fois, mais je n'avais pas vérifié si un déclencheur se compilait à chaque fois qu'il était déclenché alors qu'il ne faisait pas référence au DMV et codait en dur une valeur. Il se compilait toujours à chaque fois qu'il se déclenchait. La suppression du déclencheur arrête les compilations.
- Nous utilisons sqlserver.query_pre_execution_showplan dans une session XE pour suivre les compilations. Pourquoi y a-t-il un écart entre cela et le compteur PerfMon?
- Est-il normal que vous obteniez un événement de compilation à chaque exécution d'un déclencheur?
Script de repro:
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;