Принудительное ОБЪЕДИНЕНИЕ в OR для оптимизации в SQL Server 2000

StackOverflow https://stackoverflow.com/questions/372246

Вопрос

Как я могу получить запрос, который использует OR в предложении WHERE, чтобы разделить себя на два запроса с ОБЪЕДИНЕНИЕМ во время компиляции?Если я вручную перепишу его, запрос с использованием ОБЪЕДИНЕНИЯ будет в 100 раз быстрее, чем отдельный запрос, потому что он может эффективно использовать разные индексы в каждом запросе объединения.Есть ли какой-нибудь способ заставить оптимизатор использовать этот подход?

У меня есть запрос, который выглядит примерно так:

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3
where conditions1 
    and ((@param1 is null and cond3a) or (cond3b))

Где columnlist, joincond2, joincond3 и conditions1 - все это более длинные выражения.Фишка в том, что только одно из условий в ОПЕРАЦИОННОЙ всегда является истинным.

Сначала я подумал, что мог бы просто переписать его, чтобы выполнить объединение, но затем я повторяю columnlist, joincond2, joincond3 и conditions1, что составляет около 20 строк SQL, которые могут потребовать большого обслуживания в будущем.Есть ли подсказка, которую я могу предоставить, или какой-то лучший способ написать предложение WHERE?Заранее благодарю.

Это было полезно?

Решение

Вы можете сгруппироваться

select columnlist
from table1
join table2 on joincond2
join table3 on joincond3

в представление, а затем используйте объединение.

но если вы можете перейти на sql2005 / 8, вы можете использовать обычное табличное выражение.

with cte ( columnlist )
as (
    select columnlist
    from table1
    join table2 on joincond2
    join table3 on joincond3 )
select columnlist from cte where ...
union
select columnlist from cte where ...

Другие советы

Попробуйте добавить опцию (ПЕРЕКОМПИЛИРОВАТЬ) к запросу.Если это в хранимой процедуре, то добавьте к ней также функцию ПЕРЕКОМПИЛЯЦИИ.Может случиться так, что при первом запуске запроса SQL Server выдает план и кэширует его, но затем во второй раз он все еще использует старый (и теперь плохой) план запроса.

Вы понесете незначительный ущерб, потому что его нужно будет перекомпилировать каждый раз, когда вы используете запрос, но это будет незначительно по сравнению с использованием плохого плана.

Редактировать:Я читал, что использование WITH RECOMPILE в хранимой процедуре в SQL 2000 не всегда работает должным образом.Предположительно, ошибка была исправлена в SQL 2005.Однако я никогда не сталкивался с этой ошибкой лично, поэтому я не знаю, в чем именно с ней дело.Но все же дайте ему попробовать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top