Comment effacer tous les anciens plans de requête de Microsoft SQL Server?

12

Nous avons une application standard qui utilise une base de données Microsoft SQL. Dans cette application, nous sélectionnons différents critères de sélection pour chaque rapport. Cette application exécute ensuite ces rapports.

Je crois que nous avons un problème de plan de requête. Le premier rapport que nous exécutons chaque jour est très rapide pendant 7 minutes. Tout rapport que nous exécutons après le premier rapport prend plus d'une heure.

Chaque nuit, nous exécutons une tâche planifiée qui arrête et démarre l'Agent SQL Server et SQL Server. Il existe environ 25 autres bases de données dans cette seule instance de SQL Server. Aucune autre base de données n'a de problèmes de performances, seul celui du produit standard que j'ai mentionné plus tôt.

Existe-t-il un moyen d'effacer tous les plans de requête que SQL Server a actuellement en mémoire?

Comment puis-je faire cela sans affecter une trentaine d'utilisateurs qui dépendent d'autres bases de données sur le même serveur?

Michael Riley - AKA Gunny
la source

Réponses:

7

Mes excuses pour ma réponse précédente.

1) Ajoutez l'option WITH RECOMPILE à l'instruction CREATE PROCEDURE si vous savez que votre requête variera à chaque exécution à partir de la procédure stockée. L'option WITH RECOMPILE empêche la réutilisation du plan d'exécution de procédure stockée. SQL Server ne met donc pas en cache un plan pour cette procédure et la procédure est recompilée au moment de l'exécution. L'utilisation de l'option WITH RECOMPILE peut augmenter les performances si votre requête varie chaque fois qu'elle est exécutée à partir de la procédure stockée car dans ce cas, le mauvais plan d'exécution ne sera pas utilisé.

2) Vous devez créer un guide de plan qui utilise un indice de requête USE PLAN pour chaque type de requête (chaque type de demande de procédure stockée) pour forcer le plan d'exécution.

Voici un article sur le plan d'exécution qui peut vous aider.

garik
la source
Je suis d'accord avec WITH RECOMPILE, je l'ai fait avec des systèmes que j'ai construits. Cependant, je n'ai pas accès à la source SQL ... elle s'exécute à partir d'une application.
Michael Riley - AKA Gunny
@Cape Cod Gunny dans ce cas, essayez DBCC FLUSHPROCINDB: Utilisé pour effacer le cache de procédure stockée pour une base de données spécifique sur un serveur SQL, pas l'ensemble du serveur SQL. Vous souhaiterez peut-être utiliser cette commande avant le test pour vous assurer que les plans de procédure stockée précédents n'affecteront pas négativement les résultats du test. Exemple: DECLARE @intDBID INTEGER SET @intDBID = (SELECT dbid FROM master.dbo.sysdatabases WHERE name = 'database_name') DBCC FLUSHPROCINDB (@intDBID)
garik
le problème a été résolu. Il s'est avéré qu'une table temporaire utilisée pour stocker les critères de recherche accumulait perpétuellement des données. Le processus est censé tronquer les données de cette table avant de collecter les données. Merci pour le bel extrait sql.
Michael Riley - AKA Gunny
13

Vous avez posé deux questions ici. Tout d'abord, vous voulez savoir si vous pouvez supprimer tous les plans stockés en mémoire pour une instance de SQL. Cela se fait avec DBCC FREEPROCCACHE comme Matt M l'a suggéré.

La deuxième question que vous avez posée est "Comment puis-je faire cela sans affecter une trentaine d'utilisateurs qui dépendent d'autres bases de données sur le même serveur?". La réponse courte est "vous ne pouvez pas". Si vous supprimez tous les plans, les autres utilisateurs qui comptent sur les plans en mémoire subiront probablement une baisse de performances.

La solution de contournement pour cela nécessite une intervention manuelle. Vous pouvez utiliser DBCC FREEPROCCACHE pour supprimer des plans spécifiques à condition que vous ayez le plan_handle.

D'après ce que vous décrivez ci-dessus, cela ressemble à un problème de plan, mais je ne suis pas certain que la suppression des plans soit la réponse. Je voudrais vous indiquer la direction du reniflage des paramètres avant de penser à supprimer des plans:

http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx

Vous devriez être en mesure d'optimiser les requêtes plutôt que de vous amuser avec DBCC FREEPROCCACHE sur une base planifiée. Je vous conseille également de passer du temps à analyser les événements d'attente pour votre instance.

SQLRockstar
la source
Le DBCC FREEPROCCACHE n'a pas résolu le problème. Je surveille l'activité et les événements. Il y a 0 E / S physiques. Il semble être suspendu à cette application: .Net Sql Client Data Provider. Le type d'attente est CXPACKET.
Michael Riley - AKA Gunny
CXPACKET implique que votre requête va en parallèle. Pouvez-vous déterminer le nombre de threads en cours d'exécution pour la requête et examiner leurs attentes? Vous pouvez utiliser l'outil gratuit d'Adam Machanic WhoIsActive sqlblog.com/files/folders/release/entry29675.aspx .
SQLRockstar
7

DBCC FREEPROCCACHE

À l'aide de cette commande, vous pouvez vider le cache de procédure entier en une seule commande. Veuillez lire la documentation avant d'utiliser cette commande. Lisez la section Remarques à quelques reprises.

L'effacement du cache de procédures entraînera la recompilation des caches de procédures stockées lors de la prochaine utilisation. Cela pourrait affecter les performances. Utilisez avec précaution!

Mat

Matt M
la source
J'ai essayé d'utiliser DBCC FREEPROCCACHE et cela n'a pas résolu le problème. J'ai fini par tuer le processus après 1 heure.
Michael Riley - AKA Gunny