L'affichage d'un plan d'exécution estimé génère des attentes CXPACKET, PAGELATCH_SH et LATCH_EX [ACCESS_METHODS_DATASET_PARENT]

13

J'exécute Microsoft SQL Server 2016 SP2-CU6 (13.0.5292.0) sur une machine virtuelle 4 vCPU avec max degree of parallelismdéfini sur 2et cost threshold for parallelismdéfini sur 50.

Le matin, lorsque j'essaie d'afficher un plan d'exécution estimé pour une requête SELECT TOP 100 , je suis confronté à des attentes massives et l'opération de rendu du plan estimé prend des minutes, souvent dans la plage de 5 à 7 minutes. Encore une fois, ce n'est pas l'exécution réelle de la requête, c'est juste le processus pour afficher un plan d'exécution estimé .

sp_WhoIsActiveaffichera les PAGEIOLATCH_SHattentes ou les LATCH_EX [ACCESS_METHODS_DATASET_PARENT]attentes et lorsque j'exécute le script WaitingTasks.sql de Paul Randal pendant l'opération, il affiche les CXPACKETattentes avec les threads de travail indiquant les PAGEIOLATCH_SHattentes:

entrez la description de l'image ici

* champ de description de ressource = exchangeEvent id=Port5f6069e600 WaitType=e_waitPortOpen waiterType=Coordinator nodeId=1 tid=0 ownerActivity=notYetOpened waiterActivity=waitForAllOwnersToOpen

Les threads de travail semblent ramener la statstable entière en mémoire (comme ces numéros de page ainsi que les numéros de page suivants affichés à partir de la requête de Paul Randal pointent vers la clé en cluster pour la statstable). Une fois que le plan est revenu, il est essentiellement instantané pour le reste de la journée, même après que je vois la plupart de l' statsattrition de la table du cache avec seulement divers enregistrements restants (qui, je suppose, ont été retirés en raison de la recherche d'opérations à partir de requêtes similaires).

Je m'attendrais à ce comportement initial si la requête s'exécutait réellement avec un plan qui utilisait des opérateurs SCAN, mais pourquoi fait-il cela lors de l'évaluation des plans d'exécution uniquement pour arriver à un opérateur SEEK comme indiqué dans le plan lié ci-dessus? Que puis-je faire (en plus d'exécuter cette instruction avant les heures de bureau pour que mes données soient correctement mises en cache) pour améliorer les performances ici? Je suppose qu'une paire d'indices de couverture serait bénéfique, mais garantirait-elle vraiment tout changement de comportement? Je dois travailler dans certaines limites de la fenêtre de stockage et de maintenance ici, et la requête elle-même est générée à partir d'une solution fournisseur, donc toute autre suggestion (en plus d'une meilleure indexation) serait la bienvenue à ce stade.

John Eisbrener
la source

Réponses:

13

Il semble que votre demande d'un plan d'exécution réel ait déclenché des mises à jour des statistiques. Puisque vous mentionnez que cela se produit le matin, j'imagine qu'il y a un processus du jour au lendemain qui fait beaucoup de modifications aux tables concernées?

Ainsi, SQL Server utilise les statistiques pour créer le plan, a atteint le seuil de modification et exécute des mises à jour automatiques des statistiques dans le cadre de l'opération.

Dans le XML du plan estimé que vous avez partagé, je vois ces dates de mise à jour rapprochées pour les statistiques de ce matin:

LastUpdate="2019-05-06T09:12:49.92"
LastUpdate="2019-05-06T09:12:58.3"
LastUpdate="2019-05-06T09:13:20.33"
LastUpdate="2019-05-06T09:13:09.67"
LastUpdate="2019-05-06T09:12:59.05"
LastUpdate="2019-05-06T09:12:39.56"

S'il s'agit de tables très volumineuses et occupées (cela semble probablement basé sur les pourcentages d'échantillonnage), il n'est pas trop surprenant que les mises à jour des statistiques prennent beaucoup de puissance.

Josh Darnell
la source
9

Lorsque je vois des durées de plan estimées longues dans SSMS, c'est l'un des suivants par ordre de probabilité:

  1. L'optimiseur de requêtes a décidé qu'il devait créer ou mettre à jour des statistiques.
  2. La taille du plan estimé est très grande (disons> 10 Mo) et il faut simplement du temps à SSMS pour l'afficher.
  3. La compilation des requêtes elle-même a pris du temps en raison de l'utilisation du processeur pour rechercher un plan suffisamment bon.
  4. Le serveur est soumis à une contrainte extrême. Par exemple, je devrai peut-être attendre qu'une passerelle soit disponible.
  5. Divers bogues qui entraînent des temps de compilation extrêmement longs.

Pour votre situation, la réponse est presque certainement que SQL Server met à jour ou crée des statistiques. Il y a quelques indices: la taille du plan de requête est petite, le plan de requête est relativement simple avec un faible coût et la CPU de compilation est nettement inférieure au temps de compilation:

entrez la description de l'image ici

Le nouveau contributeur Josh Darnell a également souligné un bon indice avec la dernière mise à jour des statistiques dans le XML.

SQL Server 2019 introduit un nouveau type d'attente, WAIT_ON_SYNC_STATISTICS_REFRESH , pour les requêtes en attente de mises à jour des statistiques. Il est beaucoup plus facile de diagnostiquer ce problème sur cette version. Jusque-là, vous devrez simplement compter sur des techniques indirectes.

Les solutions de contournement incluent la mise à jour des statistiques pendant une période de maintenance ou l'activation de la mise à jour automatique des statistiques asynchrones pour la base de données. Veuillez comprendre toutes les ramifications de cette option avant de la modifier. Les plans de requête seront créés avant la mise à jour des statistiques plutôt qu'après la mise à jour des statistiques. Pour certaines charges de travail, cela peut être une énorme victoire. Pour d'autres, cela peut faire plus de mal que de bien.

Joe Obbish
la source