MSDN " Thiếu tham gia lớp sự kiện dự đoán " nói rằng " chỉ ra rằng một truy vấn đang được thực thi không có biến vị ngữ tham gia ".
Nhưng thật không may, nó dường như không dễ dàng như vậy.
Ví dụ, tình huống rất đơn giản:
create table #temp1(i int);
create table #temp2(i int);
Select * from #temp1, #temp2 option (recompile);
Không có dữ liệu trong các bảng, cũng không có cảnh báo, mặc dù rõ ràng nó không có biến vị ngữ tham gia.
Nếu tôi xem tài liệu về SQL Server 2005 (cùng một liên kết, chỉ là phiên bản máy chủ khác), có thêm một câu: " Sự kiện này chỉ được tạo ra nếu cả hai bên tham gia trả lại nhiều hơn một hàng. " Điều này sẽ tạo ra cảm giác hoàn hảo trong tình huống trước. Không có dữ liệu, vì vậy cả hai bên trả về 0 hàng và không có cảnh báo. Chèn hàng, nhận cảnh báo. Ok, tuyệt
Nhưng đối với tình huống khó hiểu tiếp theo, tôi chèn cùng một giá trị vào cả hai bảng:
Insert into #temp1 (i) values (1)
Insert into #temp1 (i) values (1)
Insert into #temp2 (i) values (1)
Insert into #temp2 (i) values (1)
Va tôi lây:
-- no warning:
Select * from #temp1 t1
inner join #temp2 t2 on t1.i = t2.i
option (recompile)
-- has warning:
Select * from #temp1 t1
inner join (select 1 i union all select 1) t2 on t1.i = t2.i
option (recompile)
Tại sao cái này rất?
Lưu ý : một số tập lệnh tôi đã sử dụng để phát hiện các truy vấn xấu này trên máy chủ của mình.
- Tất nhiên, kế hoạch thực hiện các thủ tục
sử dụng theo dõi máy chủ mặc định để tìm cảnh báo
Declare @trace nvarchar(500); Select @trace = cast(value as nvarchar(500)) From sys.fn_trace_getinfo(Null) Where traceid = 1 and property = 2; Select t.StartTime, te.name, * From sys.fn_trace_gettable(@trace, 1) t Inner join sys.trace_events te on t.EventClass = te.trace_event_id where EventClass = 80 order by t.StartTime desc
bộ đệm kế hoạch thực hiện, để tìm những kế hoạch có cảnh báo (như cái này)
WITH XMLNAMESPACES (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') SELECT Cast('<?SQL ' + st.text + ' ?>' as xml) sql_text, pl.query_plan, ps.execution_count, ps.last_execution_time, ps.last_elapsed_time, ps.last_logical_reads, ps.last_logical_writes FROM sys.dm_exec_query_stats ps with (NOLOCK) Cross Apply sys.dm_exec_sql_text(ps.sql_handle) st Cross Apply sys.dm_exec_query_plan(ps.plan_handle) pl WHERE pl.query_plan.value('(//Warnings/@NoJoinPredicate)[1]', 'bit') = 1 Order By last_execution_time desc OPTION (RECOMPILE);