CPU kullanımı yüksek olan bir sunucuda sorun gidermekteyiz. Sorguların gerçekten buna neden olmadığını belirledikten sonra, derlemeleri aramaya başladık.
Performans İzleyicisi 50 Derleme / sn'den az ve 15 Derleme / sn'den az gösteriyor.
Derlemeleri arayan bir XE oturumunu çalıştırdıktan sonra, saniyede binlerce derleme görüyoruz.
Bu sistem değişiklikleri denetlemek için tetikleyiciler kullanıyor. Derlemelerin çoğu tetikleyicilerden kaynaklanmaktadır. Tetikleyiciler referans sys.dm_tran_active_transactions.
İlk düşüncemiz, belki bir tetikleyicide bir DMV'ye referans vermenin her seferinde derlenmesine neden olacağı ya da belki de sadece bu spesifik DMV'nin buna yol açacağıydı. Ben de bu teoriyi test etmeye başladım. Her seferinde derleme yapar, ancak her tetikleyicinin DMV'ye referans vermediğinde tetiklenip tetiklenmediğini kontrol etmedim ve bunun yerine bir değer kodlardım. Her tetiklendiğinde hala derliyordu. Tetiğin bırakılması derlemeleri durdurur.
- Derlemeleri izlemek için bir XE oturumunda sqlserver.query_pre_execution_showplan kullanıyoruz. Bu ve PerfMon sayacı arasında neden bir tutarsızlık var?
- Bir tetikleyici her çalıştırıldığında bir derleme olayı almanız normal mi?
Repro betiği:
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;