Pourquoi faut-il autant de temps pour calculer un plan d'exécution?

9

Un de nos clients vient de passer à un nouveau serveur.

Pour une procédure stockée particulière, la première fois que vous l'exécutez, l'exécution prend plus de trois minutes. Les exécutions suivantes durent moins d'une seconde.

Cela m'amène à penser que les trois premières minutes sont principalement consacrées au calcul du plan d'exécution. Les exécutions suivantes utilisent alors simplement le plan mis en cache et s'exécutent instantanément.

Sur nos bases de données de test, il faut environ 5 secondes pour calculer le plan de la même procédure.

Je ne vois rien de terrible dans le plan lui-même - bien que je n'imagine pas sa pertinence car le plan montre combien de temps il faut pour exécuter la requête, pas pour se calculer.

Le serveur est un 16 cœurs avec 24 Go de mémoire. Aucune charge de processeur ou de mémoire importante ne se produit.

Qu'est-ce qui pourrait provoquer un calcul aussi lent que sur une base de données particulière?

Quelles mesures puis-je prendre pour trouver la cause du problème?

Éditer

J'ai donc réussi à accéder au serveur et à exécuter la requête avec SET SHOWPLAN_XML ON .

Je peux confirmer que le CompileTime pour la requête occupe 99% du temps d'exécution de la requête. Le StatementOptmEarlyAbortReason est "TimeOut" , sur notre base de données de test avec une copie de leur base de données, la raison est MemoryLimitExceeded.

Mongus Pong
la source
1
Êtes-vous sûr que c'est la compilation du plan qui prend beaucoup de temps, pas seulement la lecture des données dans le cache du disque?
Mark Storey-Smith
1
Le temps de compilation apparaît dans le plan XML lui-même. Avez-vous identifié le temps de compilation et non autre chose, par exemple la mise à jour automatique synchrone des statistiques? Quelle version de SQL Server utilisez-vous?
Martin Smith
@ MarkStorey-Smith Eh bien, je ne suis vraiment sûr de rien. Je sais que l'exécution de DBCC FREEPROCCACHE , qui efface uniquement le cache du plan, prendra le temps de requête suivant jusqu'à 3 minutes.
Mongus Pong
@MartinSmith Ah oui très utile, j'ai utilisé le plan de requête visuel. Oui, le temps de compilation est à peu près le temps d'exécution complet de la requête. Nous sommes sur SQL Server 2008 R2.
Mongus Pong
@MongusPong - Si vous créez une copie uniquement statistique de la base de données de production, pouvez-vous la reproduire dans votre environnement de test? Que dit le plan StatementOptmEarlyAbortReason?
Martin Smith

Réponses:

9

Je déteste répondre à ma propre question, d'autant plus que j'ai eu beaucoup d'aide de la part des autres pour trouver la solution, mais voilà.

Le problème était dû à certaines statistiques ratées dans la base de données. En regardant le plan d'exécution, l'optimiseur s'attendait à 11,5 To de données renvoyées par la requête. En réalité, il recevait 87 Ko. Je sais maintenant que d'énormes disparités entre les lignes attendues et réelles renvoyées sont un signe que les statistiques sont obsolètes.

Courir simplement

exec sp_updatestats

force la base de données à mettre à jour les statistiques de toutes les tables.

Cela a réduit le temps d'exécution des requêtes de 3 minutes à 6 secondes. Tout le monde est gagnant!

Merci pour votre aide, vous tous. : 0)

Mongus Pong
la source