MSDN " Відсутній клас приєднання предикатів " каже, що " вказує на те, що виконується запит, який не має предиката приєднання ".
Але, на жаль, це здається не таким простим.
Наприклад, дуже проста ситуація:
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);