J'ai deux requêtes presque identiques exécutées sur la même instance SQL Server 2005:
- La première est la
SELECT
requête d' origine générée par LINQ (je sais, je sais ... je ne suis pas le développeur de l'application, juste le DBA :). - Le second est exactement le même que le premier, a ajouté un
OPTION (RECOMPILE)
à la fin.
Rien d'autre n'a été changé.
Le premier prend 55 secondes à chaque exécution.
Le second prend 2 secondes.
Les deux jeux de résultats sont identiques.
Pourquoi cet indice générerait-il un gain de performances aussi spectaculaire?
L'entrée Books Online sur RECOMPILE
n'offre pas une explication très détaillée:
Demande au moteur de base de données SQL Server de supprimer le plan généré pour la requête après son exécution, forçant l'optimiseur de requête à recompiler un plan de requête la prochaine fois que la même requête est exécutée. Sans spécifier RECOMPILE, le moteur de base de données met en cache les plans de requête et les réutilise. Lors de la compilation des plans de requête, l'indicateur de requête RECOMPILE utilise les valeurs actuelles de toutes les variables locales de la requête et, si la requête se trouve dans une procédure stockée, les valeurs actuelles transmises à tous les paramètres.
RECOMPILE est une alternative utile à la création d'une procédure stockée qui utilise la clause WITH RECOMPILE lorsque seul un sous-ensemble de requêtes à l'intérieur de la procédure stockée, au lieu de la procédure stockée entière, doit être recompilé. Pour plus d'informations, consultez Recompilation des procédures stockées. RECOMPILE est également utile lorsque vous créez des repères de plan. Pour plus d'informations, consultez Optimisation des requêtes dans les applications déployées à l'aide des guides de plan.
Étant donné que ma requête contient de nombreuses variables locales, je suppose que SQL Server est en mesure de l'optimiser (sérieusement) lorsque j'utilise l' OPTION (RECOMPILE)
indicateur de requête.
Partout où je regarde, les gens disent que cela OPTION (RECOMPILE)
devrait être évité. L'explication est généralement que l'utilisation de cet indice SQL Server n'est pas en mesure de réutiliser ce plan d'exection et doit donc perdre du temps à le recompiler à chaque fois.
(Mais) Compte tenu de l'avantage de performance gigantesque, je suis enclin à penser que l'utilisation de cet indice de requête cette fois serait une bonne chose.
Dois-je l'utiliser? Sinon, existe-t-il un moyen de forcer SQL Server à utiliser un meilleur plan d'exécution sans cette indication et sans modifier l'application?