我们正在对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;