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

Configurations étendues de la base de données SQL Server et correction automatique du plan

Dans cet article, nous examinerons les configurations étendues de la base de données et la correction automatique du plan SQL Server 2017. Microsoft a ajouté de nouvelles fonctionnalités à SQL Server 2017 qui ont amélioré les performances des requêtes.

Les performances des requêtes SQL Server sont liées à la qualité et à la précision du plan d'exécution. Lorsque nous exécutons une requête, l'optimiseur de requête analyse un grand nombre de plans d'exécution, puis décide du plan d'exécution de requête optimal.

Estimation de la cardinalité héritée : L'estimateur de cardinalité prédit le nombre de lignes que la requête renverra et détermine l'allocation de mémoire de la requête.

Dans SQL Server 2017, la version par défaut du modèle d'estimation de la cardinalité est 14.0, mais si vous souhaitez utiliser l'ancienne version 7.0 de l'estimateur de cardinalité, vous pouvez le faire en modifiant l'option Estimation de la cardinalité héritée dans les configurations de portée de base de données rubrique.

La valeur par défaut de l'estimation de la cardinalité héritée est OFF. Ainsi, si vous souhaitez utiliser l'ancienne version, vous devez l'activer.

Vous pouvez également modifier cette propriété dans T-SQL.

ALTER DATABASE SCOPED CONFIGURATION SET LEGACY_CARDINALITY_ESTIMATION =OFF|ON ;

Cependant, si vous activez ce paramètre, cela affectera toutes les requêtes. Par conséquent, cela peut endommager les performances de la requête. Pour éviter cela, vous pouvez utiliser l'indice FORCE_LEGACY_CARDINALITY_ESTIMATION.

Lorsque nous exécutons cette requête dans la base de données WideWorldImporters, elle utilise automatiquement une nouvelle version de l'estimation de cardinalité.

SELECT [o].[CustomerID], o.LastEditedBy , [o].[OrderDate] FROM Sales.Orders oWHERE [o].[OrderDate]>='20140101'

Lorsque nous ajoutons FORCE_LEGACY_CARDINALITY_ESTIMATION à la requête, l'optimiseur de requête utilise la version précédente ou la plus ancienne de l'estimation de cardinalité.

MAXDOP  : nous pouvons définir le degré maximal de parallélisme pour une base de données individuelle. Avant la création de cette fonctionnalité, nous ne pouvions configurer que le niveau du serveur MAXDOP.

L'indicateur de requête MAXDOP nous permet d'exécuter des requêtes en parallèle.

ALTER DATABASE SCOPED CONFIGURATION SET MAXDOP =4 ; ALLER

Renifleur de paramètres : Lorsqu'une heure d'exécution d'une requête change considérablement et que cette modification de l'heure est liée au paramètre de la requête, on parle de reniflage de paramètre.

Nous allons maintenant créer une procédure stockée sur la base de données AdventureWorks. Nous enverrons différents paramètres et comparerons les plans d'exécution.

DROP PROCEDURE IF EXISTS Get_OrdersGOCREATE PROCEDURE Get_Orderes@ProductID INTASSELECT SalesOrderDetailID, OrderQtyFROM Sales.SalesOrderDetailWHERE ProductID =@ProductID;GO/*******Ne pas utiliser ce script dans les serveurs de production !*******/ DBCC FREEPROCCACHE--Interroger MarsEXEC Get_OrderID_OrderQty @ProductID=870DBCC FREEPROCCACHE--Interroger VenusEXEC Get_OrderID_OrderQty @ProductID=897

Comme le montre l'image ci-dessous, SQL Server génère un plan d'exécution différent pour la même requête. Le plan d'exécution de Query Mars recommande un index. Le paramètre de requête modifie le plan d'exécution optimal.

Exécutez cette requête et regardez les plans d'exécution.

DBCC FREEPROCCACHE--Interroger MarsEXEC Get_OrderID_OrderQty @ProductID=870--Interroger VenusEXEC Get_OrderID_OrderQty @ProductID=897

Le plan d'exécution de Query Venus est le même que le plan d'exécution de Query Mars. Il s'agit du reniflage de paramètre car le plan d'exécution mis en cache est compilé pour le plan d'exécution Query Mars. Pour cette raison, Query Venus utilise le même plan d'exécution.

Maintenant, nous allons désactiver le reniflage des paramètres et exécuter les mêmes requêtes.

ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SNIFFING =OFF;DBCC FREEPROCCACHE--Query MarsEXEC Get_OrderID_OrderQty @ProductID=870--Query VenusEXEC Get_OrderID_OrderQty @ProductID=897

Examinons :

L'optimiseur de requête SQL Server a généré le plan d'exécution optimal pour Query Venus et Query Mars. Cette approche offre des performances optimales à la requête.

Il existe quelques options pour éviter ce problème :

  • OPTION(RECOMPILER)
  • OPTION (OPTIMISER POUR(@VARIABLE=UNKNOWN))

Correction automatique du plan

SQL Server 2017 inclut une nouvelle fonctionnalité appelée Correction automatique du plan. Lorsque nous exécutons une requête, l'optimiseur de requête crée un plan d'exécution. Pour certaines raisons, l'optimiseur de requête choisit de mauvais plans d'exécution. Certaines des raisons sont les suivantes :

  • Une requête qui ne répond pas aux critères de performance
  • Statistiques obsolètes
  • Index inadaptés

Lorsque l'optimiseur de requête SQL Server décide de modifier le plan d'exécution et que ce plan d'exécution nuit aux performances, les performances de la requête sont appelées la régression du plan. Une nouvelle fonctionnalité est fournie avec SQL Server 2016. Cet outil aide à surveiller et à dépanner les performances des requêtes et stocke en même temps les mesures de performances et les compteurs de l'exécution de la requête.

Nous pouvons activer ces options sous les propriétés de la base de données.

Maintenant, nous allons faire une démonstration de cette fonctionnalité. Tout d'abord, videz le cache de la procédure et créez une procédure stockée.

/**************************************** N'utilisez pas ce script dans serveurs de production********************************************/USE WideWorldImportersALTER DATABASE WideWorldImporters SET QUERY_STORE =MARCHE ; ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALLDBCC FREEPROCCACHE --Cette commande effacera tout le cache de procédure dans SQL Server. N'essayez pas en production envoierment-- ALTER DATABASE WideWorldImporters SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN =OFF); DROP PROCEDURE IF EXISTS Test_CoddingSight2 GO CREATE PROC Test_CoddingSight2 @Id AS INT AS select sum([UnitPrice]*[Quantity]) from Sales.OrderLines O INNER JOIN sales.Orders o1 ON o1.OrderID =o.OrderID où o.PackageTypeID =@ Identifiant

À cette étape, nous allons exécuter cette procédure avec différents paramètres et trouver la différence de temps d'exécution.

--Query AlphaDBCC FREEPROCCACHE EXEC Test_CoddingSight2 7GO 80DBCC FREEPROCCACHE EXEC Test_CoddingSight2 -1--Query BetaEXEC Test_CoddingSight2 7GO 80

Comme vous pouvez le voir, la première requête a été complétée en 12 secondes, tandis que la seconde a été effectuée en 33 secondes. La raison de cette différence spectaculaire est que l'optimiseur de requête choisit un plan d'exécution inapproprié pour Query Beta.

Comparons les plans d'exécution de Query Alpha et Query Beta.

Plan d'exécution de Query Alpha

Plan d'exécution de Query Beta

Dans les images ci-dessus, l'optimiseur de requête crée différents plans d'exécution pour la même requête. Lorsque nous examinons les requêtes les plus consommatrices de ressources , nous pouvons voir que Query Beta consomme plus de ressources que Query Alpha.

La requête ci-dessous renverra des informations détaillées sur les recommandations de réglage.

SELECT name, reason, score, JSON_VALUE(details, '$.implementationDetails.script') as script, details.* FROM sys.dm_db_tuning_recommendations CROSS APPLY OPENJSON(details, '$.planForceDetails') WITH ( query_id int '$ .queryId', regressed_plan_id int '$.regressedPlanId', last_good_plan_id int '$.recommendedPlanId') comme détailsWHERE JSON_VALUE(state, '$.currentValue') ='Active'

La colonne des raisons indique pourquoi nous devons appliquer cette recommandation.

Maintenant, nous allons relancer Query Alpha et Query Beta avec la correction automatique du plan activée.

/****************************************Ne pas utiliser ce script dans les serveurs de production****************************************/ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALLDBCC FREEPROCCACHE /****************************************Activer la correction automatique du plan *****************************************/ALTER DATABASE WideWorldImporters SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN =SUR); --Query AlphaDBCC FREEPROCCACHE EXEC Test_CoddingSight2 7GO 80DBCC FREEPROCCACHE EXEC Test_CoddingSight2 -1--Query BetaEXEC Test_CoddingSight2 7GO 80

Après cette démo, le plan d'exécution de Query Alpha est appliqué à Query Beta. De plus, les temps d'exécution de Query Alpha et Query Beta sont proches l'un de l'autre. La requête ci-dessous renverra le statut de correction automatique du plan.

SELECT name, reason, score, JSON_VALUE(state, '$.currentValue') as status,JSON_VALUE(details, '$.implementationDetails.script') as script, details.* FROM sys.dm_db_tuning_recommendations CROSS APPLY OPENJSON(details , '$.planForceDetails') AVEC ( query_id int '$.queryId', regressed_plan_id int '$.regressedPlanId', last_good_plan_id int '$.recommendedPlanId') as detailsWHERE JSON_VALUE(state, '$.currentValue') ='Verifying' 

De plus, nous pouvons trouver des informations graphiques dans Requêtes avec plans forcés . Ce graphique définit les plans de requête forcés et la requête.

Références

Correction automatique du plan dans SQL Server 2017

Estimation de la cardinalité