Je développe un système qui périodiquement (4-5 fois par jour) exécute une instruction select, qui prend normalement moins de 10 secondes mais qui a duré jusqu'à 40 minutes.Requête lente intermittente sur SQL Server 2008
La base de données est sur Windows Server 2008 + SQL Server 2008 R2; les deux 64bit.
Il existe un service sur la machine exécutant la base de données qui interroge la base de données et génère des valeurs pour les enregistrements qui en ont besoin. Ces enregistrements sont ensuite périodiquement interrogés à l'aide d'une sélection de jointure multi-tables à partir d'un service sur une deuxième machine écrite en C++ (VS 2010) à l'aide de la classe MFC CRecordset pour extraire les données. Un exemple de la requête à l'origine du problème est illustré ci-dessous.
SELECT DISTINCT "JobKeysFrom"."Key" AS "KeyFrom","KeysFrom"."ID" AS "IDFrom",
"KeysFrom"."X" AS "XFrom","KeysFrom"."Y" AS "YFrom","JobKeysTo"."Key" AS "KeyTo",
"KeysTo"."ID" AS "IDTo","KeysTo"."X" AS "XTo","KeysTo"."Y" AS "YTo",
"Matrix"."TimeInSeconds","Matrix"."DistanceInMetres","Matrix"."Calculated"
FROM "JobKeys" AS "JobKeysFrom"
INNER JOIN "JobKeys" AS "JobKeysTo" ON
("JobKeysFrom"."Key"<>"JobKeysTo"."Key") AND
("JobKeysFrom"."JobID"=531) AND
("JobKeysTo"."JobID"=531)
INNER JOIN "Keys" AS "KeysFrom" ON
("JobKeysFrom"."Key"="KeysFrom"."Key") AND ("JobKeysFrom"."Status"=4)
INNER JOIN "Keys" AS "KeysTo" ON
("JobKeysTo"."Key"="KeysTo"."Key") AND ("JobKeysTo"."Status"=4)
INNER JOIN "Matrix" AS "Matrix" ON
("Matrix"."IDFrom"="KeysFrom"."ID") AND ("Matrix"."IDTo"="KeysTo"."ID")
ORDER BY "JobKeysFrom"."Key","JobKeysTo"."Key"
J'ai essayé ce qui suit
- vérifié les indices et tous semblent corrects et ils sont actifs et sont utilisés conformément à la requête
- le conseiller en conception revient sans suggestions
- J'ai essayé de défragmenter les index et les données
- reconstruit la base de données à partir de zéro en exportant les données et en les réimportant dans une nouvelle base de données.
- a exécuté le profileur sur elle et a constaté que quand il va mal, il semble faire plusieurs millions (jusqu'à 100 millions) de lectures plutôt que de quelques centaines de milliers.
- couru la base de données sur un autre serveur
Pendant le temps est en cours d'exécution de la requête, je peux courir exactement la même requête dans la fenêtre du studio de gestion et il sera de retour à la course en 10 secondes. Le problème ne semble pas être lié au verrou, à l'interblocage, au processeur, au disque ou à la mémoire, comme il l'a fait lorsque la machine exécutant la base de données n'exécutait qu'une seule requête. Le serveur a 4 processeurs et 16 Go de mémoire pour l'exécuter. J'ai également essayé de mettre à jour les disques à des plus rapides et cela n'a eu aucun effet.
Il me semble que c'est presque comme si la base de données recevait la requête, commençait à la traiter et puis se met en veille pendant 40 minutes ou exécute la requête sans utiliser les index.
Lorsque cela prend du temps, il finit par finir et envoie les résultats de la requête (normalement environ 70-100000 enregistrements) à l'application appelante.
Toute aide ou suggestions reçus avec reconnaissance, merci beaucoup
Cette requête est-elle exécutée en tant que procédure stockée paramétrée? –
Pouvez-vous éviter le SELECT DISTINCT? Cela peut nuire gravement à la performance. –
@Yves: semble assez performant pour fonctionner ad hoc, et revient en 10 secondes. –