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;
la source
Non. Les déclencheurs ne sont pas toujours recompilés. Les instructions de requête simples, cependant, ne mettent pas leurs plans en cache et sont donc toujours recompilées.
Les déclencheurs sont recompilés si le nombre de lignes insérées ou supprimées change considérablement. Voir: https://technet.microsoft.com/en-us/library/ms181055.aspx
Je ne sais pas s'ils ont les mêmes dans XEvents, mais dans SQL Trace, une recompilation a une sous-classe d'événements qui vous explique pourquoi elle a été recompilée. Cela est expliqué dans le même lien ci-dessus.
la source