2010-10-19 5 views
6

Exemple de requête:Pourquoi la version paramétrée de cette requête est-elle plus lente qu'une version non paramétrée?

CREATE PROCEDURE dbo.Test (@p varchar(10)) 
AS 
DECLARE @param varchar(10) 
SET @param = @p + '%' 

SELECT * FROM table1 t1 
INNER JOIN table2 t2 on t1.id = tr.id 
WHERE t2.desc LIKE @param 

J'ai une requête qui est similaire à celle ci-dessus et quand j'utilise cette procédure stockée il fonctionne indéfiniment sans donner aucune sortie. Mais si j'utilise la même requête que,

SELECT * FROM table1 t1 
INNER JOIN table2 t2 on t1.id = tr.id 
WHERE t2.desc LIKE 'A%' -- notice no parameter here 

Ceci s'exécute en moins d'une seconde.

Mon table2 a 140K records et table1 certains 250K

Toute idée de ce qui pourrait être à l'origine comme opérateur de courir lentement?

+0

Avez-vous regardé un plan d'explication pour la requête? –

+0

D'après vos tests, il semble que cela n'ait rien à voir avec un mot-clé similaire, puisque même la version rapide inclut cet opérateur. – JohnFx

+0

J'ai essayé de courir les deux et il court moins d'une seconde quand j'utilise les paramètres directement. –

Répondre

4

Il ne sait pas au moment de la compilation que @param ne comportera pas de caractère générique de premier plan, alors lorsqu'il compile le lot, il vous donne un plan avec un balayage et non une recherche.

Vous pouvez peut-être essayer OPTION (RECOMPILE) ou OPTION (FORCESEEK) (SQL Server 2008) pour voir si cela vous donne un meilleur plan.

+0

+1 et merci de me mettre directement sur la variable locale. –

+0

OPTION (RECOMPILE) travaillé. Maintenant, il court moins d'une seconde. Ma requête d'origine a 4 jointures internes et 3 jointures externes gauche. –

+0

@rs - Après avoir fait quelques tests mais je commence à douter de mon explication. Lorsque je regarde le plan de procédure stockée, je vois que les deux se retrouvent avec une recherche de gamme d'index. La version paramétrée possède un opérateur scalaire de calcul qui appelle 'LikeRangeStart' et' LikeRangeEnd'. Il utilise réellement cette plage de recherche même lorsqu'il y a un premier caractère générique. À quoi ressemblent vos plans d'exécution? Vous vous demandez si la collation peut faire une différence (ou peut-être que c'est juste une question de statistiques faussées, ce qui signifie qu'elle modifie l'ordre des opérateurs) –