2011-03-31 4 views
0

Je voudrais savoir si existe une commande pour forcer NO RECOMPILE d'une procédure stockée. J'ai une procédure qui prend environ 5 minutes à exécuter. Mais lorsque je cours directement dans les fenêtres de requête, cela ne prend que quelques secondes. Ce sp a une table temporaire.SQL Server - force NO recompiler procédure stockée

Ma question est: Y at-il un moyen de forcer une procédure stockée pour éviter la recompilation ???

Note: J'utilise SQL Server 2005.

+2

Je ne pense pas que cela ait quelque chose à voir avec la compilation. Vous devez établir la raison réelle que cela prend plus de temps dans une procédure stockée que directement dans une fenêtre de requête. Je vous suggère de commencer par regarder les plans de requête pour voir s'ils sont identiques. – Ben

+0

Quand vous dites "5 minutes à exécuter", quelle est l'interface pour l'exécuter? Une application client? –

+1

['OPTION (KEEPFIXED PLAN)'] (http://msdn.microsoft.com/fr-fr/library/ee343986%28v=sql.100%29.aspx). Mais s'il a un comportement différent lorsqu'il est exécuté à partir de SSMS avec les mêmes paramètres, je suspecterais un reniflage de paramètre. –

Répondre

2

Comme il a été souligné dans les commentaires, ce qui est presque certainement rien à voir avec recompilation plan. Si je dois deviner, cela est dû à un mauvais plan de requête provoqué par le reniflage des paramètres. Supposons que vous avez un site Web de commerce électronique où nous pouvons obtenir des ventes différentes. Nous aurons beaucoup plus d'adresses en Californie qu'en Alaska, n'est-ce pas? Les opérations physiques que SQL Server va effectuer pour lire beaucoup de données (ventes résumées en Californie) vont être très différentes de ce qu'elles demandent pour lire un peu de données (ventes résumées en Alaska). Parfois, les plans mis en cache sont excellents pour un seul ensemble de paramètres et sont horribles pour tous les autres. Ceci est souvent appelé sniffing de paramètre.

Il ya un article fantastique sur Parameter Sniffing disponible sur le site de Simple Talk. Donc, vous pouvez éviter de lire cela, vous n'avez pas beaucoup d'options en dehors de spécifier OPTION (RECOMPILE) au niveau de l'instruction, en spécifiant WITH RECOMPILE au niveau de la procédure, ou en copiant les paramètres de la procédure dans des variables locales et en utilisant ceux pour exécuter votre requête paramétrée.

+2

Et en utilisant 'OPTIMIZE FOR' –

+0

Vous pourriez théoriquement utiliser quelque chose comme' OPTIMIZE FOR (@my_var = NULL) 'ou quelque chose de similaire, mais cela pourrait aussi aboutir à de mauvais plans de nature différente. 'WITH RECOMPILE' donnera le meilleur plan pour chaque exécution et les paramètres de copie vous donneront un plan universellement merdique. –

0

Notez que les plans SQL Server sont mis en cache par les options SET ainsi que par le texte de la requête. En d'autres termes, si vous disposez de différentes options SET dans Management Studio, vous pouvez voir un comportement différent de celui de l'application.

Pour vérifier les options SET pour chaque connexion, regardez les quoted_identifier, arithabort, ANSI_NULL_DFLT_ON, ANSI_DEFAULTS, ANSI_WARNINGS, ANSI_PADDING, ansi_nulls et colonnes CONCAT_NULL_YIELDS_NULL des sys.dm_exec_sessions vue de gestion dynamique. Pour mon problème récent, ADO.NET avait mis ARITHABORT OFF, alors que Management Studio l'avait activé. Pour modifier les options d'une fenêtre de requête dans Management Studio, cliquez avec le bouton droit de la souris dans l'éditeur de requête et sélectionnez Options de requête dans le menu contextuel, puis accédez à la page Advanced pour ARITHABORT et CONCAT_NULL_YIELDS_NULL et la page ANSI pour QUOTED_IDENTIFIER et les options ANSI. Sinon, exécutez simplement les options SET nécessaires dans cette fenêtre de requête.

Une fois que vous avez le même environnement mis en place, vérifier les différences entre le plan d'exécution estimé et le plan d'exécution réelle . Le plan estimé sera calculé en utilisant les paramètres et les statistiques disponibles à cet instant, alors que le plan réel sera celui qui est dans le cache. Les chances sont que les plans soient différents, et vous avez besoin de mettre à jour les statistiques, de les guider selon les paramètres les plus typiques, de forcer une recompilation à chaque fois ou de réécrire la requête pour qu'elle soit plus stable. Par exemple, si vous avez des paramètres optionnels, envisagez d'utiliser des instructions IF/ELSE plutôt que d'essayer d'être intelligent en disant 'WHERE @param = -1 ou Column = @param', qui se comportera très différemment si @param n'est pas fourni. Ou, utilisez SQL dynamique pour construire le texte.

Vous devez savoir que les statistiques sont optimales lorsque la première colonne des statistiques, à savoir la première colonne de l'index pour les statistiques d'index, est la plus sélective et la plus fréquemment mise à jour.SQL Server produit un histogramme détaillé pour la première colonne uniquement - jusqu'à 200 valeurs de cette colonne avec le nombre de lignes dans chaque plage. Pour les autres combinaisons de colonnes, il calcule simplement une valeur de sélectivité moyenne, le nombre de combinaisons uniques divisé par le nombre de lignes échantillonnées. Il met également à jour automatiquement les statistiques uniquement lorsqu'un nombre suffisant de modifications s'est produit dans la colonne principale. Voir http://blogs.technet.com/b/rob/archive/2008/05/16/sql-server-statistics.aspx pour plus d'informations sur la mise à jour des statistiques.