Do trình kích hoạt biên dịch mỗi lần?


22

Chúng tôi đang khắc phục sự cố một máy chủ có mức sử dụng CPU cao. Sau khi thấy rằng các truy vấn không thực sự gây ra nó, chúng tôi bắt đầu xem xét các phần tổng hợp.

Màn hình hiệu suất đang hiển thị dưới 50 Biên dịch / giây và dưới 15 Biên dịch / giây.

Sau khi chạy một phiên XE tìm kiếm các phần tổng hợp, chúng ta đang thấy hàng ngàn phần tổng hợp mỗi giây.

Hệ thống này đang sử dụng các kích hoạt để kiểm toán thay đổi. Hầu hết các phần tổng hợp là do kích hoạt. Các tham chiếu kích hoạt sys.dm_tran_active_transilities.

Suy nghĩ đầu tiên của chúng tôi là có thể việc tham chiếu DMV trong trình kích hoạt sẽ khiến nó biên dịch mỗi lần, hoặc có thể chỉ DMV cụ thể này sẽ gây ra nó. Vì vậy, tôi bắt đầu thử nghiệm lý thuyết đó. Nó không biên dịch mỗi lần, nhưng tôi đã không kiểm tra nếu trình kích hoạt biên dịch mỗi lần nó được kích hoạt khi nó không tham chiếu DMV và thay vào đó mã hóa một giá trị. Nó vẫn đang biên dịch mỗi khi nó được kích hoạt. Thả kích hoạt dừng biên dịch.

  1. Chúng tôi đang sử dụng sqlserver.query_pre_execut_showplan trong một phiên XE để theo dõi các phần tổng hợp. Tại sao có sự khác biệt giữa điều đó và bộ đếm PerfMon?
  2. Có phải là bình thường khi bạn nhận được một sự kiện biên dịch mỗi khi kích hoạt chạy?

Kịch bản 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;

Câu trả lời:


20

Sự kiện XE đang được sử dụng đang khiến bạn không chính xác nghĩ rằng trình kích hoạt thực sự đang biên dịch mọi thực thi. Có hai sự kiện mở rộng query_pre_execut_showplan và query_post_compilation_showplan có mô tả tương tự, nhưng khác nhau bởi một từ quan trọng:

query_pre_execut_showplan

Xảy ra sau khi một câu lệnh SQL được biên dịch. Sự kiện này trả về một đại diện XML của kế hoạch truy vấn ước tính được tạo khi truy vấn được tối ưu hóa . Sử dụng sự kiện này có thể có chi phí hoạt động đáng kể vì vậy chỉ nên sử dụng khi khắc phục sự cố hoặc theo dõi các sự cố cụ thể trong khoảng thời gian ngắn.

truy vấn_post_compilation_showplan

Xảy ra sau khi một câu lệnh SQL được biên dịch. Sự kiện này trả về một đại diện XML của kế hoạch truy vấn ước tính được tạo khi truy vấn được biên dịch . Sử dụng sự kiện này có thể có chi phí hoạt động đáng kể vì vậy chỉ nên sử dụng khi khắc phục sự cố hoặc theo dõi các sự cố cụ thể trong khoảng thời gian ngắn.

Các sự kiện không giống hệt nhau trong mô tả và xảy ra vào các thời điểm khác nhau từ thử nghiệm thêm bằng cách sử dụng repro của bạn. Sử dụng một định nghĩa phiên sự kiện lớn hơn nhiều, thật dễ dàng để biết nơi các phần tổng hợp thực sự đang diễn ra.

nhập mô tả hình ảnh ở đây

Ở đây bạn có thể thấy quá trình biên dịch đầu tiên xảy ra đối với các câu lệnh chèn khi các gói được chuẩn bị được tự động tham số hóa trong hộp màu xanh lá cây. Trình kích hoạt được biên dịch trong hộp màu đỏ và gói được chèn vào bộ đệm như được hiển thị bởi sự kiện sp_cache_insert. Sau đó, trong hộp màu cam, thực thi kích hoạt được nhấn bộ đệm và sử dụng lại kế hoạch kích hoạt cho câu lệnh INSERT thứ hai trong lô, do đó, nó không biên dịch mọi thực thi của lệnh INSERT và kế hoạch sẽ được sử dụng lại như bạn có thể thấy với sự kiện sp_cache_hit cho kích hoạt.

Nếu chúng ta chạy hai câu lệnh INSERT một lần nữa sau lần thực thi đầu tiên, trình kích hoạt sẽ không biên dịch lại như được hiển thị trong các sự kiện dưới đây:

nhập mô tả hình ảnh ở đây

Ở đây, câu lệnh đầu tiên gặp phải một lần nhấn bộ đệm cho phiên bản tự động được tham số hóa của câu lệnh trong bộ đệm nhưng lại bỏ lỡ lô adhoc đã được gửi. Trình kích hoạt nhận được một lần nhấn bộ đệm và không biên dịch lại như được hiển thị trong khối sự kiện màu đỏ. Khối sự kiện màu xanh lá cây lặp lại hành vi này cho câu lệnh INSERT thứ hai chạy dưới dạng một lô riêng biệt. Tuy nhiên, trong mọi trường hợp, bạn vẫn thấy sự kiện bắn_pre_execut_showplan bắn mà tôi chỉ có thể quy cho sự khác biệt trong việc được tối ưu hóa so với được biên dịch trong mô tả sự kiện, nhưng trình kích hoạt không biên dịch cho mọi thực thi như được hiển thị bởi các chuỗi sự kiện này.


Nếu bạn nhìn vào ảnh chụp màn hình đầu tiên, sự kiện sql_batch_statistic không có trong bộ sưu tập nhưng chỉ kích hoạt lần thực hiện đầu tiên của lô sql khi bộ đệm bị xóa và kế hoạch tự động tham số hóa cho INSERT không nằm trong bộ đệm của kế hoạch. Sau đó, sự kiện unsached_sql_batch_statistic không kích hoạt lại.
Jonathan Kehayias

Query_post_compilation_showplan chỉ hiển thị một vài phần tổng hợp trên các trình kích hoạt nhưng không phải là số lượng lớn chúng ta đã thấy trong sự kiện khác. Chúng tôi đã tìm thấy một số cố định thú vị với query_post_compilation_showplan. Cảm ơn thông tin, Jonathan!
Tara Kizer

13

Không. Triggers không phải lúc nào cũng được biên dịch lại. Tuy nhiên, các câu lệnh truy vấn đơn giản không được lưu bộ đệm của chúng và do đó sẽ luôn được biên dịch lại.

Kích hoạt sẽ được biên dịch lại nếu số lượng hàng được chèn hoặc xóa thay đổi đáng kể. Xem: https://technet.microsoft.com/en-us/l Library / ms181055.aspx

Tôi không biết liệu chúng có giống nhau trong XEvents không, nhưng trong SQL Trace, một bộ biên dịch lại có một lớp con sự kiện cho bạn biết lý do tại sao nó được biên dịch lại. Điều đó được giải thích trong cùng một liên kết ở trên.


1
Chúng tôi đã xem xét các phần tổng hợp hơn là các phần tổng hợp. Chúng ta sẽ xem xét máy chủ vào ngày mai và kiểm tra xem đó là do một câu lệnh truy vấn đơn giản hay nếu đó là do số lượng hàng. Cảm ơn!
Tara Kizer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.