MSDN " Join Join Predicate 이벤트 클래스가 누락되었습니다 "는 " Join 술어 가없는 쿼리가 실행되고 있음을 나타냅니다 ."
그러나 불행히도 그렇게 쉬운 것처럼 보이지는 않습니다.
예를 들어 매우 간단한 상황은 다음과 같습니다.
create table #temp1(i int);
create table #temp2(i int);
Select * from #temp1, #temp2 option (recompile);
테이블에는 데이터가 없으며 조인 술어도 없지만 경고는 없습니다.
SQL Server 2005 (동일한 링크, 다른 서버 버전)에 대한 설명서를 살펴보면 다음과 같은 추가 문장이 있습니다. " 이 이벤트는 조인의 양쪽이 둘 이상의 행을 반환하는 경우에만 생성됩니다. " 이전 상황에서의 완벽한 의미. 데이터가 없으므로 양쪽에서 0 개의 행을 반환하고 경고는 없습니다. 행을 삽입하고 경고를 받으십시오. 그래요 좋아요.
그러나 다음 혼란 상황에서는 두 테이블에 동일한 값을 삽입합니다.
Insert into #temp1 (i) values (1)
Insert into #temp1 (i) values (1)
Insert into #temp2 (i) values (1)
Insert into #temp2 (i) values (1)
그리고 나는 얻는다 :
-- 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)
왜 그렇습니까?
참고 : 서버에서 이러한 잘못된 쿼리를 감지하는 데 사용한 일부 스크립트.
- 물론, 절차의 실행 계획
경고를 찾기 위해 기본 서버 추적을 사용했습니다.
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
실행 계획 캐시, 경고가있는 계획 (예 : 이와 같은 계획)
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);