Question

Comment puis-je obtenir une requête qui utilise un OU dans la clause WHERE de se diviser en deux requêtes avec une UNION lors de la compilation? Si je réécris manuellement, la requête en utilisant l'UNION est 100x plus rapide que la seule requête, car il peut utiliser efficacement différents indices dans chaque requête du syndicat. Est-il possible que je puisse faire l'optimiseur utiliser cette approche?

J'ai une requête qui ressemble à quelque chose comme ceci:

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

Où COLUMNLIST, joincond2, joincond3 et conditions1 sont toutes les expressions plus longues. Le botteur est que seule une des conditions du OU est toujours vrai.

J'ai d'abord pensé que je pouvais réécrire pour faire l'union, mais je répète COLUMNLIST, joincond2, joincond3 et conditions1, qui est 20 ou si des lignes de SQL qui pourraient avoir besoin de beaucoup d'entretien à l'avenir. Y at-il un indice que je peux fournir ou une meilleure façon d'écrire la clause WHERE? Merci à l'avance.

Était-ce utile?

La solution

Vous pouvez regrouper

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

dans une vue, puis utilisez l'union.

mais si vous pouvez migrer vers sql2005 / 8, vous pouvez utiliser l'expression de table commune.

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

Autres conseils

Essayez d'ajouter OPTION (RECOMPILE) à la requête. Si elle est dans une procédure stockée puis ajouter WITH RECOMPILE à cela aussi. Il se peut que la première fois que vous exécutez la requête SQL Server est livré avec un plan et il met en cache mais la deuxième fois par qu'il utilise encore l'ancien (et maintenant pauvres) plan de requête.

Vous prenez un coup mineur, car il devra recompiler chaque fois que vous utilisez la requête, mais il sera infime par rapport à l'utilisation d'un mauvais plan.

EDIT: J'ai lu que l'utilisation WITH RECOMPILE dans une procédure stockée dans SQL 2000 ne fonctionne pas toujours correctement. Le bogue a été soi-disant résolu dans SQL 2005. Je ne l'ai jamais rencontré personnellement le bug, donc je ne sais pas ce que l'affaire est exacte avec elle. Faites un essai bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top