2008-12-16 10 views
2

Comment puis-je obtenir une requête qui utilise un OU dans la clause WHERE pour se scinder en deux requêtes avec UNION lors de la compilation? Si je le réécris manuellement, la requête utilisant l'UNION est 100 fois plus rapide que la requête unique, car elle peut utiliser efficacement différents index dans chaque requête de l'union. Y a-t-il un moyen pour que l'optimiseur utilise cette approche?Forcer UNION sur un OU pour l'optimisation dans SQL Server 2000

J'ai une requête qui ressemble à 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 kicker est que seule une des conditions dans la RO est toujours vraie. J'ai d'abord pensé que je pouvais simplement le réécrire pour faire l'union, mais ensuite je répète columnlist, joincond2, joincond3, et conditions1, qui est une vingtaine de lignes de SQL qui pourraient nécessiter beaucoup de maintenance dans le futur. Y at-il un indice que je peux fournir ou une meilleure façon d'écrire la clause WHERE? Merci d'avance.

+0

Est-ce que cond3a ou cond3b se rapportent à l'une des conditions de jointure? –

Répondre

4

Vous pouvez regrouper

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

en 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 ... 
+0

Pas exactement ce que j'espérais, mais ça va marcher pour le moment. Merci. –

0

Essayez d'ajouter OPTION (RECOMPILE) à la requête. Si c'est dans une procédure stockée, ajoutez également WITH RECOMPILE à cela. Il se peut que la première fois que vous exécutez la requête SQL Server propose un plan et le mette en cache, mais la seconde fois, il utilise toujours l'ancien plan de requête (et maintenant médiocre).

Vous obtiendrez un succès mineur car il devra recompiler chaque fois que vous utiliserez la requête, mais il sera minuscule par rapport à l'utilisation d'un mauvais plan.

EDIT: J'ai lu que l'utilisation de WITH RECOMPILE dans une procédure stockée dans SQL 2000 ne fonctionne pas toujours correctement. Le bug a été soi-disant corrigé dans SQL 2005. Je n'ai jamais rencontré le bogue personnellement, donc je ne sais pas quel est l'accord exact avec ça. Essayez-le cependant.