MSDN " Missing Join Predicate Event Class " indique qu'il " indique qu'une requête est en cours d'exécution qui n'a pas de prédicat de jointure ".
Mais malheureusement, cela ne semble pas être aussi simple que cela.
Par exemple, situation très simple:
create table #temp1(i int);
create table #temp2(i int);
Select * from #temp1, #temp2 option (recompile);
Il n'y a pas de données dans les tableaux, il n'y a pas d'avertissement non plus, bien qu'il n'y ait évidemment aucun prédicat de jointure.
Si je jette un œil à la documentation de SQL Server 2005 (le même lien, juste une autre version de serveur), il y a une phrase supplémentaire: " Cet événement est produit uniquement si les deux côtés de la jointure renvoient plus d'une ligne. " sens parfait dans la situation précédente. Il n'y a pas de données, les deux côtés renvoient donc 0 lignes et aucun avertissement. Insérez des lignes, recevez un avertissement. OK cool.
Mais pour la prochaine situation déroutante, j'insère les mêmes valeurs dans les deux tableaux:
Insert into #temp1 (i) values (1)
Insert into #temp1 (i) values (1)
Insert into #temp2 (i) values (1)
Insert into #temp2 (i) values (1)
Et je reçois:
-- 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)
Pourquoi cela est-il ainsi?
Remarque : certains scripts que j'ai utilisés pour détecter ces mauvaises requêtes sur mon serveur.
- bien sûr, plan d'exécution des procédures
utilisé la trace du serveur par défaut pour rechercher les avertissements
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 du plan d'exécution, pour trouver ces plans avec des avertissements (comme celui-ci)
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);