Pergunta

Como posso obter uma consulta que usa um OR na cláusula WHERE para dividir-se em duas consultas com a União durante a compilação? Se eu reescrevê-lo manualmente, a consulta usando o UNION é 100x mais rápido que a única consulta, porque ele pode usar eficazmente índices diferentes em cada consulta do sindicato. Existe alguma maneira eu posso fazer o otimizador de usar essa abordagem?

Eu tenho uma consulta que é algo como isto:

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

Onde ColumnList, joincond2, joincond3 e conditions1 são todas expressões mais longas. O kicker é que apenas uma das condições no OR é sempre verdadeiro.

A primeira vez que pensei que eu poderia simplesmente reescrevê-lo a fazer a união, mas então eu estou repetindo ColumnList, joincond2, joincond3 e conditions1, que é 20 ou mais linhas de SQL que podem precisar de muita manutenção no futuro. Existe uma dica que eu posso fornecer ou algum melhor maneira de escrever a cláusula WHERE? Agradecemos antecipadamente.

Foi útil?

Solução

Você pode agrupar

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

para uma visualização, e depois uso união.

mas se você pode migrar para sql2005 / 8, você pode usar expressão de tabela comum.

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 ...

Outras dicas

Tente adicionar OPÇÃO (RECOMPILE) para a consulta. Se está em um procedimento armazenado, em seguida, adicionar WITH RECOMPILE para isso também. Pode ser que a primeira vez que você executar a consulta SQL Server vem com um plano e armazena em cache-lo, mas, em seguida, na segunda vez ele ainda está usando o plano de consulta antigo (e agora pobres).

Você vai tomar uma batida menor, porque ele vai precisar recompilar cada vez que você usar a consulta, mas será minúscula em comparação com o uso de um plano de pobres.

EDIT: Eu li que usando WITH RECOMPILE em um procedimento armazenado no SQL 2000 nem sempre funciona corretamente. O bug foi supostamente corrigido no SQL 2005. Eu nunca encontrei o bug pessoalmente, então eu não sei qual é o problema exato é com ele. Experimentá-lo embora.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top