Tetikleyiciler her seferinde derlenir mi?


22

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.

  1. 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?
  2. 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;

Yanıtlar:


20

Kullanılan XE olayı, tetikleyicinin aslında her yürütmeyi derlediğini düşünmeniz için sizi yanlış yönlendiriyor. Query_pre_execution_showplan ve query_post_compilation_showplan'da benzer tanımlara sahip, ancak önemli bir kelimeden farklı iki genişletilmiş olay vardır:

query_pre_execution_showplan

Bir SQL ifadesi derlendikten sonra oluşur. Bu olay, sorgu optimize edildiğinde oluşturulan tahmini sorgu planının XML gösterimini döndürür . Bu olayın kullanılması önemli bir performans yüküne sahip olabileceğinden, yalnızca kısa bir süre için belirli sorunları giderirken veya izlerken kullanılmalıdır.

query_post_compilation_showplan

Bir SQL ifadesi derlendikten sonra oluşur. Bu olay, sorgu derlendiğinde oluşturulan tahmini sorgu planının XML gösterimini döndürür . Bu olayın kullanılması önemli bir performans yüküne sahip olabileceğinden, yalnızca kısa bir süre için belirli sorunları giderirken veya izlerken kullanılmalıdır.

Olaylar açıklamada tam olarak aynı değildir ve raporunuzu kullanarak daha sonraki testlerden farklı zamanlarda ortaya çıkar. Çok daha büyük bir olay oturumu tanımı kullanarak, derlemelerin gerçekte nerede olduğunu görmek kolaydır.

görüntü tanımını buraya girin

Burada, yeşil kutuda otomatik olarak parametrelendirilen hazırlık planları olarak insert ifadelerinin ilk derlemesini görebilirsiniz. Tetikleyici kırmızı kutuda derlenir ve plan, sp_cache_insert olayı tarafından gösterildiği gibi önbelleğe eklenir. Ardından turuncu kutuda tetikleyici yürütme önbellek isabetini alır ve toplu işteki ikinci INSERT deyimi için tetikleyici planını yeniden kullanır, böylece INSERT komutunun her yürütmesini derlemez ve plan sp_cache_hit olayıyla görebileceğiniz gibi yeniden kullanılır tetikleyici için.

İki INSERT deyimini ilk çalıştırmadan sonra ayrı ayrı çalıştırırsak, tetikleyici aşağıdaki olaylarda gösterildiği gibi tekrar derlenmez:

görüntü tanımını buraya girin

Burada ilk ifade, cümlenin hazırlamasının otomatik parametreli sürümü için önbellekte bir önbellek isabetiyle karşılaşır, ancak gönderilen geçici toplu iş için özledim. Tetikleyici bir önbellek isabetine neden olur ve kırmızı olay bloğunda gösterildiği gibi bir daha derlenmez. Yeşil olay bloğu, bu davranışı ayrı bir toplu iş olarak çalışan ikinci INSERT ifadesi için tekrarlar. Ancak, her durumda yine query_pre_execution_showplan olay ateş gördüğümüz elimden sadece ediliyor farkı nitelik optimize vs derlenmiş olay açıklamasında, ama olayların bu dizi ile gösterildiği gibi tetikleyici her yürütülmesi için derleme değildir.


İlk ekran görüntüsüne bakarsanız, önbelleğe alınmamış sql_batch_statistics olayı koleksiyondadır, ancak önbellek temizlendiğinde ve INSERT'ler için otomatik olarak parametrelenmiş plan plan önbelleğinde olmadığında yalnızca sql toplu işleminin ilk yürütülmesi için tetiklenir. Bundan sonra uncached_sql_batch_statistics olayı bir daha ateşlenmez.
Jonathan Kehayias

Query_post_compilation_showplan, tetikleyiciler üzerinde sadece birkaç derleme gösterdi ancak diğer olayla ilgili gördüğümüz büyük miktarla değil. Query_post_compilation_showplan ile bazı ilginç külçeler bulduk. Bilgi için teşekkürler Jonathan!
Tara Kizer

13

Hayır. Tetikleyiciler her zaman yeniden derlenmez. Bununla birlikte, basit sorgu ifadeleri planlarını önbelleğe almaz ve bu nedenle daima yeniden derlenir.

Takılan veya silinen satır sayısı önemli ölçüde değişirse, tetikleyiciler yeniden derlenir. Bakınız: https://technet.microsoft.com/en-us/library/ms181055.aspx

XEvents'ta da aynı olup olmadıklarını bilmiyorum, ancak SQL Trace'da bir yeniden derleme, neden yeniden derlendiğini söyleyen bir olay alt sınıfına sahiptir. Bu yukarıda aynı bağlantıda açıklanmıştır.


1
Yeniden derlemelerden ziyade derlemelere bakıyorduk. Sunucuya yarın bakacağız ve bunun basit bir sorgu ifadesi olup olmadığını mı yoksa satır sayısından mı kaynaklandığını kontrol edeceğiz. Teşekkürler!
Tara Kizer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.