Database
 sql >> Base de données >  >> RDS >> Database

Suivi des mises à jour des statistiques synchrones

Présentation

L'optimiseur de requête SQL Server utilise des statistiques lors de la compilation de la requête pour aider à déterminer le plan de requête optimal. Par défaut, si l'optimiseur remarque qu'une statistique est obsolète en raison d'un trop grand nombre de modifications apportées à une table, il mettra à jour la statistique immédiatement avant que la compilation de la requête puisse continuer (uniquement les statistiques dont il a besoin, pas toutes les statistiques de la table) .

Notez que "trop" n'est pas spécifique car il varie selon la version et si l'indicateur de trace 2371 est activé - voir la section AUTO_UPDATE_STATISTICS de cette page pour plus de détails.

Le problème des mises à jour de statistiques synchrones

La mise à jour synchrone des statistiques avant la compilation introduit évidemment un délai et rend la requête plus longue à compiler et à exécuter. L'ampleur d'un retard dépend de plusieurs facteurs, notamment :

  • Combien de tables impliquées dans la requête ont atteint le seuil "trop ​​de modifications"
  • Combien de statistiques pour chacune de ces tables doivent être mises à jour car elles sont nécessaires pour la compilation
  • Combien de lignes il y a dans les tables concernées
  • Les options spécifiées lors de la création de chaque statistique (par exemple, FULLSCAN et PERSIST_SAMPLE_PERCENT=ON)

Ainsi, il peut y avoir un délai apparemment aléatoire, ce qui peut causer des problèmes dans certains scénarios, en particulier si une application a un délai d'attente de requête très faible.

Éviter les mises à jour de statistiques synchrones

Il existe plusieurs façons d'éviter les mises à jour synchrones des statistiques, telles que :

  • Définir AUTO_UPDATE_STATISTICS sur OFF, ce qui désactive toutes les mises à jour automatiques et signifie que vous devrez effectuer votre propre maintenance des statistiques pour éviter la possibilité de plans de requête sous-optimaux à partir de statistiques obsolètes.
  • En définissant AUTO_UPDATE_STATISTICS_ASYNC sur ON, ainsi, lorsque l'optimiseur remarque qu'une statistique doit être mise à jour, il continue la compilation et une tâche en arrière-plan met à jour la statistique un peu plus tard. Cela ne fonctionne que si vous avez également défini AUTO_UPDATE_STATISTICS sur ON.
  • Effectuez une maintenance régulière des statistiques, de sorte que les mises à jour automatiques synchrones ou asynchrones des statistiques ne se produisent pas du tout.

Il y a beaucoup de débats dans la communauté SQL Server sur l'opportunité d'activer les mises à jour statistiques asynchrones. J'ai demandé à ma charmante épouse, Kimberly L. Tripp, quelle est son opinion, et elle recommande toujours de l'activer, et elle a oublié plus de statistiques que je n'en saurai jamais, alors je la crois. ☺

Suivi des mises à jour des statistiques synchrones

Il n'y a jamais eu de moyen évident de savoir si une requête prenait beaucoup de temps parce qu'elle attendait une mise à jour synchrone des statistiques. Vous pourriez savoir *après* la fin de la mise à jour des statistiques si vous aviez déjà une session d'événements étendus en cours d'exécution en surveillant les auto_stats événement et filtrage sur async colonne étant définie sur 0. Cependant, cette colonne dans la sortie de l'événement n'a été ajoutée que dans SQL Server 2017, et vous devez également configurer une action qui capture quelque chose pour identifier la requête impliquée.

Maintenant, dans SQL Server 2019, il y a le type d'attente WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, et à première vue, il semble qu'il vous permettrait facilement de voir si une requête attend une mise à jour synchrone des statistiques en regardant simplement dans sys.dm_os_waiting_tasks pour voir ce que la requête est actuellement en attente.

Malheureusement, ce n'est pas le cas.

Le terme "en attente" est un peu trompeur ici car dans ce cas, le fil n'attend pas réellement. Ce nouveau type d'attente est un exemple de ce qu'on appelle une attente "préemptive", où le thread passe dans un mode où il reste sur le processeur jusqu'à ce qu'il ait terminé son travail. La plupart des attentes préventives se produisent lorsqu'un thread effectue un appel en dehors de SQL Server (par exemple, pour obtenir des informations de sécurité d'un contrôleur de domaine), mais parfois un thread fait quelque chose à l'intérieur de SQL Server et doit le terminer avant d'être potentiellement forcé de céder le processeur parce que son quantum de thread de 4 ms a expiré. Aucune de ces choses n'est ce qui se passe ici. Dans ce cas, le thread enregistre le début d'une attente préemptive avec le nouveau type d'attente, puis effectue la mise à jour des statistiques, entraînant probablement d'autres attentes * réelles * comme PAGEIOLATCH_SH en cours de route. Ce n'est qu'une fois la mise à jour des statistiques terminée que l'attente préventive prend fin et est prise en compte dans les statistiques d'attente.

Pourquoi est-ce un gros problème ? Eh bien, le DMV sys.dm_os_waiting_tasks montre les types d'attente pour tous les threads qui sont * vraiment * en attente, c'est-à-dire sur la liste des tâches en attente d'un planificateur, donc si le thread de mise à jour des statistiques synchrones n'attend pas WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE, ce type d'attente n'apparaîtra pas dans la sortie du DMV. Le nouveau type d'attente ne peut pas être utilisé pour voir si une requête attend actuellement une mise à jour des statistiques.

Vous pouvez facilement vous le prouver en procédant comme suit :

  • Créer un tableau avec quelques centaines de milliers de lignes
  • Créez une statistique sur une colonne de table et spécifiez FULLSCAN et PERSIST_SAMPLE_PERCENT =ON comme options, forçant la table entière à être lue à chaque fois que la statistique est mise à jour
  • Mettre à jour vingt mille lignes
  • Vérifiez la base de données et exécutez DBCC DROPCLEANBUFFERS
  • Faites une instruction SELECT avec une clause WHERE sur la colonne avec la statistique que vous avez créée
  • Regardez dans sys.dm_os_waiting_tasks DMV pour l'ID de session du SELECT, et vous verrez qu'il attend probablement PAGEIOLATCH_SH pendant que la mise à jour des statistiques lit le tableau

Cette déception mise à part, il existe une astuce pour pouvoir voir si une requête attend une mise à jour synchrone des statistiques. Lorsqu'une mise à jour des statistiques se produit, une commande appelée STATMAN s'exécute et vous pouvez la voir se produire dans la sortie de sys.dm_exec_requests :le statut sera "suspendu" (même si le thread est en cours d'exécution, comme je l'ai décrit ci-dessus), et la commande sera "SELECT (STATMAN)."

À quoi sert le nouveau type d'attente ?

Bien que le nouveau type d'attente ne puisse pas être utilisé comme moyen immédiat d'indiquer qu'une requête attend une mise à jour des statistiques synchrones, s'il apparaît dans votre analyse régulière des statistiques d'attente, vous savez que certaines requêtes de la charge de travail peuvent souffrir de ces retards. . Mais c'est à peu près la limite de son utilité en ce qui me concerne. À moins que le temps d'attente moyen n'apparaisse comme un pourcentage inquiétant du temps d'exécution moyen de vos requêtes ou que vous ne captiez continuellement les attentes sur de courtes périodes pour permettre une analyse appropriée, vous ne savez pas avec certitude s'il y a un problème.

Il s'agit d'un type d'attente où le temps d'attente peut varier énormément, en fonction des facteurs que j'ai mentionnés plus tôt. Par conséquent, j'utiliserais uniquement la présence de ce type d'attente pour être alerté des problèmes potentiels, et je voudrais implémenter une session d'événements étendus comme décrit ci-dessus pour capturer des instances de mises à jour de statistiques synchrones pour voir si leur durée est suffisamment longue pour mériter prendre des mesures correctives.

Résumé

Je ne suis pas sûr que l'ajout du type d'attente WAIT_ON_SYNCHRONOUS_STATISTICS_UPDATE va changer si les gens configurent les mises à jour de statistiques asynchrones ou font simplement toute la maintenance des statistiques eux-mêmes, mais au moins maintenant vous pourrez dire si les requêtes attendent des statistiques synchrones mises à jour et prendre d'autres mesures.

Jusqu'à la prochaine fois, bon dépannage des performances !