MSDN " Classe evento predicato join mancante " afferma che " indica che è in esecuzione una query che non ha predicato di join ".
Ma sfortunatamente non sembra essere così facile.
Ad esempio, situazione molto semplice:
create table #temp1(i int);
create table #temp2(i int);
Select * from #temp1, #temp2 option (recompile);
Non ci sono dati nelle tabelle, né avvisi, anche se ovviamente non ha predicato di join.
Se do un'occhiata alla documentazione di SQL Server 2005 (lo stesso collegamento, solo un'altra versione del server), c'è una frase in più: " Questo evento viene prodotto solo se entrambi i lati del join restituiscono più di una riga " . senso perfetto nella situazione precedente. Non ci sono dati, quindi entrambe le parti restituiscono 0 righe e nessun avviso. Inserisci righe, ricevi avviso. Ok bello.
Ma per la prossima situazione confusa, inserisco gli stessi valori in entrambe le tabelle:
Insert into #temp1 (i) values (1)
Insert into #temp1 (i) values (1)
Insert into #temp2 (i) values (1)
Insert into #temp2 (i) values (1)
E ottengo:
-- 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)
Perché è così?
Nota : alcuni script che ho usato per rilevare queste cattive query sul mio server.
- ovviamente, piano di esecuzione delle procedure
utilizzato la traccia del server predefinito per trovare gli avvisi
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
cache del piano di esecuzione, per trovare quei piani con avvisi (come questo)
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);