J'exécute Microsoft SQL Server 2016 SP2-CU6 (13.0.5292.0) sur un vCPU 4 VM avec max degree of parallelism
mis à 2
et cost threshold for parallelism
mis à 50
.
Le matin, lorsque j'essaie d'afficher une requête Plan d'exécution estimé pour un SELECT TOP 1 , je suis confronté à des attentes massives et l'opération de rendu du plan estimé prend des minutes, souvent des 5 à 7 minutes gamme. 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_WhoIsActive
affichera soit PAGEIOLATCH_SH
attend ou LATCH_EX [ACCESS_METHODS_DATASET_PARENT]
attend et quand j'exécute le script WaitingTasks.sql de Paul Randal pendant l'opération, il montre CXPACKET
attend avec les threads de travail montrant PAGEIOLATCH_SH
attend:
* 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 l'intégralité de la table stats
en mémoire (comme ces numéros de page ainsi que les numéros de page suivants affichés depuis le point de requête de Paul Randal vers la clé en cluster de la table stats
). 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'attrition de la table stats
du cache avec seulement divers enregistrements restants (que je suppose ont été extraits en raison de la recherche d'opérations 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 fenêtre de stockage et de maintenance ici, et la requête elle-même est générée à partir d'une solution de fournisseur, donc toute autre suggestion (en plus d'une meilleure indexation) serait la bienvenue à ce stade.
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"
Si ce sont de très grandes tables 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.
Lorsque je vois des durées de plan estimées longues dans SSMS, c'est l'un des suivants par ordre de probabilité:
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:
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.