sql-server – 每次执行触发器编译吗?
我们正在解除CPU操作率高的处事器.在发明查询不是真正导致它之后,我们开始研究编译. 机能监督器表现少于50次Compilations / sec和少于15次Recompilations / sec. 在运行XE会话探求编译之后,我们每秒看到数千个编译. 该体系行使触发器来考核改观.大大都汇编都是触发身分.触发器引用sys.dm_tran_active_transactions. 我们的第一个设法是,也许在触发器中引用DMV会导致它每次编译,可能也许只是这个特定的DMV会导致它.以是我开始测试这个理论.它每次城市编译,但我没有搜查触发器是否在每次触发时城市编译,由于它没有引用DMV而是硬编码一个值.它每次被触发时仍在编译.删除触发器会遏制编译. >我们在XE会话中行使sqlserver.query_pre_execution_showplan来跟踪编译.为什么它与PerfMon计数器之间存在差别? 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; 办理要领正在行使的XE变乱导致您错误地以为触发器现实上正在编译每次执行.有两个扩展变乱query_pre_execution_showplan和query_post_compilation_showplan具有相似的描写,但有一个重要的差异之处:query_pre_execution_showplan
query_post_compilation_showplan
变乱在描写中并不完全沟通,而且在行使您的repro进一步测试的差异时刻产生.行使更大的变乱会话界说,很轻易看到现实产生的编译. 在这里,您可以看到插入语句的第一次编译,由于筹备好的打算在绿色框中自动参数化.触发器在赤色框中编译,而且打算将插入到缓存中,如sp_cache_insert变乱所示.然后在橙色框中,触发器执行得到缓存掷中并从头行使批处理赏罚中第二个INSERT语句的触发器打算,因此它不会编译INSERT呼吁的每次执行,而且打算会从头行使,由于您可以看到sp_cache_hit变乱触发器. 假如我们在第一次执行后再次单独运行两个INSERT语句,则触发器不会再次编译,如下面的变乱所示: 这里第一个语句碰着缓存掷中的缓存掷中,该缓存掷中包罗缓存中语句的自动参数化版本,可是提交的adhoc批处理赏罚未掷中.触发器得到缓存掷中,而且不会再次编译,如赤色变乱块中所示.对付作为单独批处理赏罚运行的第二个INSERT语句,绿色变乱块一再此举动.可是,在每种环境下,您如故会看到query_pre_execution_showplan变乱触发,我只能将其归因于在变乱描写中优化与编译之间的差别,但触发器不会针对每个执行举办编译,如这些变乱系列所示. (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |