2015-06-02 3 views
0

Я столкнулся с ситуацией, когда запрос работает очень долго, и в плане выполнения отображается ПРОГРАММА MISSING JOIN PREDICATE прямо в проблемном месте.«Missing Join Predicate» с COALESCE

Вот ситуация в примере кода (реальный код слишком долго, чтобы получить возможность отправлять):

Запрос:

Select a, b, c 
from table1 t1 
join view v1 
on t1.id = v1.id 
join table3 t3 
on v1.value = t3.value 
...more joining... 
where [where conditions here] 

Вид:

Select X, W, Coalesce(s1.value, s2.value, s3.value) as [value] 
from table1 s1 
left join table2 s2 
on s1.id = s2.id 
left join table3 s3 
on s1.id = s3.id 

Поэтому у меня есть запрос, использует представление, которое имеет столбец, созданный с использованием COALESCE. Этот столбец коалесценции затем используется в запросе для присоединения к другим таблицам и т. Д.

ПРИМЕЧАНИЕ. Мне нужно использовать коалесц или что-то подобное, так как я не знаю, какая таблица (s1, s2 или s3) -null и, следовательно, используется для значения этого столбца.

В плане выполнения указано НЕПРАВИЛЬНОЕ СОПУТСТВУЮЩЕЕ ПРОГНОЗИРОВАНИЕ для соединения с использованием этой колонны просмотра коалесценции. Я предполагаю, что это показывает это, потому что coalesce представляет собой недетерминированную ценность?

Я пробовал переписывать запрос с помощью CTE или путем добавления кода представления непосредственно к самому запросу ... но до тех пор, пока оператор coalesce используется для соединения, я получаю медленное время запроса и MISSING JOIN PREDICATE.

Единственный способ, которым я нашел это, - использовать временную таблицу. Я загружаю результаты просмотра в #Table, а затем присоединяюсь к #Table в моем запросе ... когда я делаю это, он работает через 2-3 секунды и оттягивает 73 000 записей. Если я использую первую версию запроса/просмотра, она запускает 20+ мин. и убивает tempdb.

Я могу использовать версию таблицы temp, но есть ли еще более элегантный способ справиться с этой ситуацией ... надеюсь, все в рамках одного запроса?

Спасибо,

Джордж

+1

Вы можете разместить полный запрос? С полузаписью трудно отлаживать. – TTeeple

+0

Попробуйте упростить запрос, чтобы найти проблему.Затем, если вы можете воспроизвести проблему, используя более короткий запрос, отредактируйте свой вопрос и включите его. –

+0

Синтаксис верен, но оптимизатор, похоже, имеет проблемы с этим соединением. Он должен делать это подобно вашему обходному пути и материализовать результат, но это, похоже, делает нечто вроде CROSS JOIN. Обновлена ​​ли статистика? – dnoeth

ответ

0

Doing присоединяется на представлении часто выполняет плохо, так как таблица реально не существует (его просто сохраненный запрос, SQL работает, когда ему это нужно). Я бы предложил использовать выбор из представления в подзапросе. Оптимизатор должен работать с этим легче.

Выберите, B, C
из table1 t1
присоединиться к
(Выбрать X, W, Coalesce (s1.value, s2.value, s3.value) в виде [значение]
из table1 s1
влево присоединиться table2 s2
на s1.id = s2.id
покинул присоединиться Table3 s3
на s1.id = s3.id), как view1
на t1.id = v1.id
присоединиться Table3 t3
на v1.value = t3.value
... далее присоединение ...
где [где условия здесь]

Смежные вопросы