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

Le magasin de requêtes SQL Server

Benjamin Nevarez est un consultant indépendant basé à Los Angeles, en Californie, spécialisé dans le réglage et l'optimisation des requêtes SQL Server. Il est l'auteur de "SQL Server 2014 Query Tuning &Optimization" et "Inside the SQL Server Query Optimizer" et co-auteur de "SQL Server 2012 Internals". Avec plus de 20 ans d'expérience dans les bases de données relationnelles, Benjamin a également été conférencier lors de nombreuses conférences SQL Server, notamment le PASS Summit, SQL Server Connections et SQLBits. Le blog de Benjamin se trouve à l'adresse http://www.benjaminnevarez.com et il est également joignable par e-mail à l'adresse admin de benjaminnevarez dot com et sur twitter à @BenjaminNevarez.

Avez-vous déjà trouvé une régression de plan après une mise à niveau de SQL Server et avez-vous voulu savoir quel était le plan d'exécution précédent ? Avez-vous déjà rencontré un problème de performances de requête en raison du fait qu'une requête a reçu de manière inattendue un nouveau plan d'exécution ? Lors du dernier PASS Summit, Conor Cunningham a découvert une nouvelle fonctionnalité SQL Server, qui peut être utile pour résoudre les problèmes de performances liés à ces changements et à d'autres changements dans les plans d'exécution.

Cette fonctionnalité, appelée Query Store, peut vous aider à résoudre les problèmes de performances liés aux changements de plan et sera bientôt disponible sur SQL Azure et plus tard sur la prochaine version de SQL Server. Bien qu'il soit prévu d'être disponible sur l'édition Enterprise de SQL Server, on ne sait pas encore s'il sera disponible sur Standard ou sur toute autre édition. Pour comprendre les avantages du magasin de requêtes, permettez-moi de parler brièvement du processus de dépannage des requêtes.

Pourquoi une requête est-elle lente ?

Une fois que vous avez détecté qu'un problème de performances est dû au fait qu'une requête est lente, l'étape suivante consiste à découvrir pourquoi. Évidemment, tous les problèmes ne sont pas liés aux changements de plan. Il peut y avoir plusieurs raisons pour lesquelles une requête qui fonctionnait bien est soudainement lente. Parfois, cela peut être lié à un blocage ou à un problème avec d'autres ressources système. Quelque chose d'autre a peut-être changé, mais le défi peut être de savoir quoi. Souvent, nous n'avons pas de référence sur l'utilisation des ressources système, les statistiques d'exécution des requêtes ou l'historique des performances. Et généralement, nous n'avons aucune idée de ce qu'était l'ancien plan. Il se peut que certaines modifications, par exemple des données, un schéma ou des paramètres de requête, obligent le processeur de requêtes à produire un nouveau plan.

Modifications de forfait

Lors de la session, Conor a utilisé l'outil Picasso Database Query Optimizer Visualizer, bien qu'il ne l'ait pas mentionné par son nom, pour montrer pourquoi les plans dans la même requête ont changé, et a expliqué le fait que différents plans pouvaient être sélectionnés pour la même requête en fonction de la sélectivité de leurs prédicats. Il a même mentionné que l'équipe de l'optimiseur de requêtes utilise cet outil, qui a été développé par l'Indian Institute of Science. Un exemple de visualisation (cliquez pour agrandir) :

Visualiseur d'optimisation de requête de base de données Picasso

Chaque couleur du diagramme est un plan différent, et chaque plan est sélectionné en fonction de la sélectivité des prédicats. Un fait important est que lorsqu'une limite est franchie dans le graphique et qu'un plan différent est sélectionné, la plupart du temps, le coût et les performances des deux plans doivent être similaires, car la sélectivité ou le nombre estimé de lignes ne changent que légèrement. Cela peut se produire par exemple lorsqu'une nouvelle ligne est ajoutée à une table qui se qualifie pour le prédicat utilisé. Cependant, dans certains cas, principalement en raison des limitations du modèle de coût de l'optimiseur de requête dans lequel il n'est pas en mesure de modéliser quelque chose correctement, le nouveau plan peut présenter une grande différence de performances par rapport au précédent, ce qui crée un problème pour votre application. Soit dit en passant, les plans affichés sur le diagramme sont le plan final sélectionné par l'optimiseur de requêtes, ne confondez pas cela avec les nombreuses alternatives que l'optimiseur doit prendre en compte pour n'en sélectionner qu'une.

Un fait important, à mon avis, que Conor n'a pas couvert directement, était le changement de plans en raison de régressions après des changements sur les mises à jour cumulatives (CU), les service packs ou les mises à niveau de version. Une préoccupation majeure qui vient à l'esprit avec les changements à l'intérieur de l'optimiseur de requête est les régressions de plan. La peur des régressions de plan a été considérée comme le plus grand obstacle aux améliorations de l'optimiseur de requêtes. Les régressions sont des problèmes introduits après l'application d'un correctif à l'optimiseur de requête, et parfois appelées le classique "deux ou plusieurs torts font un bien". Cela peut arriver lorsque, par exemple, deux mauvaises estimations, l'une surestimant une valeur et l'autre la sous-estimant, s'annulent, donnant heureusement une bonne estimation. Corriger une seule de ces valeurs peut maintenant conduire à une mauvaise estimation qui peut avoir un impact négatif sur le choix de la sélection du plan, provoquant une régression.

Que fait le magasin de requête ?

Conor a mentionné que le magasin de requêtes fonctionne et peut aider avec les éléments suivants :

  1. Stocker l'historique des plans de requête dans le système ;
  2. Capturer les performances de chaque plan de requête au fil du temps ;
  3. Identifier les requêtes qui ont "été ralenties récemment" ;
  4. Vous permet de forcer les plans rapidement ; et,
  5. Assurez-vous que cela fonctionne lors des redémarrages du serveur, des mises à niveau et des recompilations de requêtes.

Ainsi, cette fonctionnalité stocke non seulement les plans et les informations de performances des requêtes associées, mais peut également vous aider à forcer facilement un ancien plan de requête, ce qui, dans de nombreux cas, peut résoudre un problème de performances.

Comment utiliser le magasin de requêtes

Vous devez activer le magasin de requêtes en utilisant le ALTER DATABASE CURRENT SET QUERY_STORE = ON; déclaration. Je l'ai essayé dans mon abonnement SQL Azure actuel, mais l'instruction a renvoyé une erreur car il semble que la fonctionnalité ne soit pas encore disponible. J'ai contacté Conor et il m'a dit que la fonctionnalité serait bientôt disponible.

Une fois le magasin de requêtes activé, il commencera à collecter les plans et les données de performances des requêtes et vous pourrez analyser ces données en consultant les tables du magasin de requêtes. Je peux actuellement voir ces tables sur SQL Azure mais, comme je n'ai pas pu activer le magasin de requêtes, les catalogues n'ont renvoyé aucune donnée.

Vous pouvez analyser les informations collectées soit de manière proactive pour comprendre les changements de performances des requêtes dans votre application, soit de manière rétroactive en cas de problème de performances. Une fois que vous avez identifié le problème, vous pouvez utiliser les techniques traditionnelles de réglage des requêtes pour essayer de résoudre le problème, ou vous pouvez utiliser le sp_query_store_force_plan procédure stockée pour forcer un plan précédent. Le plan doit être capturé dans le magasin de requêtes pour être forcé, ce qui signifie évidemment qu'il s'agit d'un plan valide (au moins lorsqu'il a été collecté ; nous en reparlerons plus tard) et qu'il a été généré par l'optimiseur de requêtes auparavant. Pour forcer un plan, vous avez besoin du plan_id , disponible dans le sys.query_store_plan catalogue. Une fois que vous regardez les différentes métriques stockées, qui sont très similaires à ce qui est stocké par exemple dans sys.dm_exec_query_stats , vous pouvez prendre la décision d'optimiser pour une métrique spécifique, comme le processeur, les E/S, etc. Ensuite, vous pouvez simplement utiliser une déclaration comme celle-ci :

EXEC sys.sp_query_store_force_plan @query_id = 1, @plan_id = 1;

Cela indique à SQL Server de forcer le plan 1 sur la requête 1. Techniquement, vous pourriez faire la même chose en utilisant un guide de plan, mais ce serait plus compliqué et vous devriez d'abord collecter et trouver manuellement le plan requis.

Comment fonctionne le magasin de requêtes ?

En fait, forcer un plan utilise des repères de plan en arrière-plan. Conor a mentionné que "lorsque vous compilez une requête, nous ajoutons implicitement un indice USE PLAN avec le fragment du plan XML associé à cette instruction". Vous n'avez donc plus besoin d'utiliser un guide de plan. Gardez également à l'esprit que, tout comme l'utilisation d'un guide de plan, il n'est pas garanti d'avoir exactement le plan forcé mais au moins quelque chose de similaire. Pour un rappel du fonctionnement des guides de plan, consultez cet article. De plus, vous devez savoir qu'il existe certains cas où forcer un plan ne fonctionne pas, un exemple typique étant lorsque le schéma a changé, c'est-à-dire si un plan stocké utilise un index mais que l'index n'existe plus. Dans ce cas, SQL Server ne peut pas forcer le plan, effectuera une optimisation normale et enregistrera le fait que l'opération de forçage du plan a échoué dans le sys.query_store_plan catalogue.

Architecture

Chaque fois que SQL Server compile ou exécute une requête, un message est envoyé au magasin de requêtes. Ceci est illustré ci-dessous.

Présentation du flux de travail du magasin de requêtes

Les informations de compilation et d'exécution sont d'abord conservées en mémoire, puis enregistrées sur le disque, en fonction de la configuration du magasin de requêtes (les données sont agrégées selon le INTERVAL_LENGTH_MINUTES paramètre, qui par défaut est d'une heure, et vidé sur le disque selon le DATA_FLUSH_INTERVAL_SECONDS paramètre). Les données peuvent également être vidées sur le disque en cas de pression de la mémoire sur le système. Dans tous les cas, vous pourrez accéder à toutes les données, à la fois en mémoire et sur disque, lorsque vous exécuterez le sys.query_store_runtime_stats catalogue.

Catalogues

Les données collectées sont conservées sur le disque et stockées dans la base de données utilisateur où le magasin de requêtes est activé (et les paramètres sont stockés dans sys.database_query_store_options . Les catalogues Query Store sont :

sys.query_store_query_text Requête d'informations textuelles
sys.query_store_query Texte de la requête plus le plan utilisé affectant les options SET
sys.query_store_plan Plans d'exécution, y compris l'historique
sys.query_store_runtime_stats Statistiques d'exécution des requêtes
sys.query_store_runtime_stats_interval Heure de début et de fin des intervalles
sys.query_context_settings Informations sur les paramètres de contexte de requête

Vues du magasin de requêtes

Les statistiques d'exécution capturent toute une série de mesures, y compris la moyenne, le dernier, le minimum, le maximum et l'écart type. Voici l'ensemble complet des colonnes pour sys.query_store_runtime_stats :

runtime_stats_id plan_id runtime_stats_interval_id
execution_type execution_type_desc first_execution_time last_execution_time count_executions
avg_duration last_duration min_duration max_duration stdev_duration
avg_cpu_time last_cpu_time min_cpu_time max_cpu_time stdev_cpu_time
avg_logical_io_reads last_logical_io_reads min_logical_io_reads max_logical_io_reads stdev_logical_io_reads
avg_logical_io_writes last_logical_io_writes min_logical_io_writes max_logical_io_writes stdev_logical_io_writes
avg_physical_io_reads last_physical_io_reads min_physical_io_reads max_physical_io_reads stdev_physical_io_reads
avg_clr_time last_clr_time min_clr_time max_clr_time stdev_clr_time
avg_dop last_dop min_dop max_dop stdev_dop
avg_query_max_used_memory last_query_max_used_memory min_query_max_used_memory max_query_max_used_memory stdev_query_max_used_memory
avg_rowcount last_rowcount min_rowcount max_rowcount stdev_rowcount

Colonnes dans sys.query_store_runtime_stats

Ces données ne sont capturées que lorsque l'exécution de la requête se termine. Le magasin de requêtes considère également le SET de la requête options, qui peuvent avoir un impact sur le choix d'un plan d'exécution, car elles affectent des choses comme les résultats de l'évaluation des expressions constantes pendant le processus d'optimisation. J'aborde ce sujet dans un article précédent.

Conclusion

Ce sera certainement une fonctionnalité intéressante et quelque chose que j'aimerais essayer dès que possible (au fait, la démo de Conor montre "SQL Server 15 CTP1" mais ces bits ne sont pas accessibles au public). Le magasin de requêtes peut être utile pour les mises à niveau qui peuvent être une CU, un service pack ou une version de SQL Server, car vous pouvez analyser les informations collectées par le magasin de requêtes avant et après pour voir si une requête a régressé. (Et si la fonctionnalité est disponible dans les éditions inférieures, vous pouvez même le faire dans un scénario de mise à niveau SKU.) Le savoir peut vous aider à prendre des mesures spécifiques en fonction du problème, et l'une de ces solutions pourrait être de forcer le plan précédent. comme expliqué précédemment.