Les suspects habituels:
- constantes dans adhoc, paramètres dans le code
- incompatibilité des types de données dans le code
- reniflement des paramètres
Point 1: l'optimiseur peut choisir le meilleur plan pour les constantes.
Changer les constantes = changer le plan. Un plénum paramétré est réutilisable
Le point 2 introduira des conversions implicites en raison de la priorité du type de données,
par exemple la colonne varchar par rapport au paramètre nvarchar
Point 3: utiliser le masquage des paramètres ou OPTIMISER POUR INCONNU
Modifier: Pour tester: exécuter le proc stocké, exécuter sp_updatestats, réexécuter. Cela invalidera les plans mis en cache, ce qui est mieux que de vider le cache du plan
Edit: après le commentaire de jcolebrand
Vous pouvez désactiver le reniflement de plusieurs manières. Les 3 principaux sont
- RECOMPILE. C'est idiot IMO.
- OPTIMISER (sic) POUR INCONNU
- Masquage des paramètres
Masquage des paramètres:
DECLARE @MaskedParam varchar(10)
SELECT @MaskedParam = @SignaureParam
SELECT...WHERE column = @MaskedParam
Le masquage et l'indice OPTIMIZE ont le même effet (peut-être pour des raisons différentes). Autrement dit, l'optimiseur doit utiliser des statistiques et la distribution des données ( Remarque: toujours en cours de test par Mark Storey-Smith ) évaluer les paramètres sur leurs propres mérites ? , plutôt que ce qu'ils étaient lors du dernier appel. L'optimiseur peut recompiler ou non. SQL Server 2005 a ajouté une recompilation au niveau des instructions afin qu'il y ait moins d'impact
Maintenant, pourquoi un plan avec des paramètres "reniflés" est "collant" par rapport aux paramètres masqués / "inconnus", je ne suis pas sûr.
J'ai utilisé le masquage des paramètres depuis SQL Server 2000 pour tout sauf le code le plus simple. J'ai remarqué que cela pouvait se produire avec un code plus complexe. Et à mon ancien travail, j'ai quelques rapports procs que je pouvais changer les valeurs par défaut des paramètres du plan. Je pense que l'approche "culte du fret" était plus facile qu'un appel de support.
Edit 2, 12 oct 2011, après quelques discussions
Le masquage des paramètres et OPTIMISER POUR INCONNU ont le même effet pour autant que je sache.
L'astuce est plus propre que le masquage mais a été ajoutée avec SQL Server 2008.
Le reniflage des paramètres se produit au moment de la compilation.
WITH RECOMPILE génère un nouveau plan à chaque exécution. Cela signifie qu'un mauvais choix de valeurs par défaut influencera le plan. Lors de mon dernier travail, j'ai pu le démontrer facilement avec du code de rapport: la modification des valeurs par défaut des paramètres a modifié le plan indépendamment des paramètres fournis.
Cet article MS Connect est intéressant: utilisation d'index sous-optimale dans la procédure stockée (mentionnée dans l'une des réponses SO ci-dessous)
- Bob Beauchemin le mentionne aussi
Problèmes en suspens
Le reniflement s'applique-t-il toujours à WITH RECOMPILE? Autrement dit, si l'optimiseur sait rejeter le plan, vise-t-il à le réutiliser?
Pourquoi les plans reniflés sont-ils "collants"?
Liens depuis SO:
WHERE
clause?