L'environnement:
Nous avons deux machines Windows Server 2003 R2 32 bits exécutant SQL Server 2005. Les configurations matérielles sont des serveurs identiques avec un processeur Xeon 5160, 4 Go de RAM et 13 Go de RAID0. Les drapeaux AWE et / 3GB ne sont pas activés.
Les serveurs ont été configurés côte à côte à l'aide d'une liste de contrôle d'installation prédéfinie, et TOUS les logiciels installés sont les mêmes sur les deux machines.
Chaque paramètre d'installation de SQL Server et chaque niveau de correctif que nous savons vérifier sont identiques. Une différence est que TEMPDB est de 400 Mo sur la machine rapide et 1,2 Go sur la machine lente. Cependant, dans les deux cas, nous ne voyons aucune allocation TEMPDB en cours.
Le problème:
Il existe une procédure stockée qui s'exécute en 2 secondes sur l'un, mais 15 minutes sur l'autre. Pendant les 15 minutes supplémentaires, il y a peu ou pas d'activité sur le disque, aucun changement d'utilisation de la mémoire, mais un cœur de processeur est épinglé à 100% tout le temps.
Ce comportement persiste même lorsque les bases de données sont sauvegardées de l'une et restaurées sur l'autre.
Puisqu'il s'agit d'une procédure stockée, le moniteur d'activité et le profileur ne nous montrent aucun détail sur l' endroit où la procédure stockée se déroule.
La question:
Que devrions-nous regarder d'autre?
Suivre:
La lenteur se produit dans les instructions FETCH NEXT pour la définition de curseur suivante:
DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...
Chacune des instructions FETCH - sur une table contenant seulement environ 1000 lignes - nécessite environ 7,25 minutes. (Non, je ne sais pas pourquoi il en fait deux de suite, il faut demander aux développeurs, mais il fonctionne correctement sur les deux serveurs).
Je suis un peu méfiant de ce "PAS DANS (SÉLECTIONNER ...)", car il semble que les lectures virtuelles soient vraiment élevées.
la source
Réponses:
L'utilisation d'une méthodologie de dépannage des performances comme les attentes et les files d'attente identifie la raison de la consommation élevée du processeur, puis une action appropriée peut être recommandée une fois le goulot d'étranglement identifié.
la source
SQL Server sélectionne un plan différent sur l'autre case.
La restauration supprimera généralement les problèmes basés sur les statistiques, donc je regarderais les différences de serveur.
Quelques vérifications grossières en premier. Ne présumez pas: vérifiez
Sautez ensuite à l'extrémité profonde, selon la réponse de Remus.
la source
Si toutes les autres choses sont égales, il est probable (selon la réponse de @ gbn) qu'un plan d'exécution différent soit généré sur chaque serveur. Comme exercice académique, il serait intéressant de voir les deux plans, alors récupérez-les dans le cache du plan sur chaque serveur et ajoutez-les à votre question si possible. Nous pouvons alors identifier les différences dans les plans qui provoquent une si grande variation de performance.
Pour une solution rapide, jetez un œil à l' astuce USE PLAN . Cela permet d'attacher le bon plan du serveur rapide à la procédure stockée sur le serveur lent.
Edit: mise à jour suivante re: curseur
Une autre variation sur votre requête pour essayer que je ne vois pas mentionnée dans d'autres réponses:
la source
Faites-moi plaisir et essayez de remplacer:
avec ça:
Je ne pense pas que cela devrait se manifester comme un problème de performances dans la partie FETCH NEXT FROM de votre code, mais je n'ai pas encore reçu mon injection de caféine. Essayez ma suggestion et faites-le moi savoir.
J'espère que cela t'aides,
Mat
la source
Vérifiez vos index et mettez à jour toutes vos statistiques. J'ai eu un problème très similaire et il s'est avéré que les statistiques sur une machine étaient bancales.
la source
J'ai connu ce même comportement deux fois et je vais vous dire ce qui l'a corrigé à chaque fois:
1.) J'ai ajouté le conseil WITH RECOMPILE à la procédure stockée car le plan mis en cache était terrible.
2.) J'ai changé la procédure stockée pour utiliser des tables temporaires au lieu de variables de table.
J'espère que l'une ou l'autre de ces aides. Bonne chance.
la source