L'administrateur de base de données s'efforce toujours d'ajuster les performances des requêtes SQL Server. La première étape du réglage des performances des requêtes consiste à analyser le plan d'exécution d'une requête. Sous certaines conditions, SQL Server Query Optimizer peut créer différents plans d'exécution. À ce stade, je voudrais ajouter quelques notes sur SQL Server Query Optimizer. SQL Server Query Optimizer est un optimiseur basé sur les coûts qui analyse les plans d'exécution et décide du plan d'exécution optimal pour une requête. Le mot-clé important pour SQL Server Query Optimizer est un plan d'exécution optimal qui n'est pas nécessairement le meilleur plan d'exécution. C'est pourquoi, si SQL Server Query Optimizer essaie de trouver le meilleur plan d'exécution pour chaque requête, cela prend plus de temps et cela nuit aux performances de SQL Server Engine. Dans SQL Server 2016, Microsoft a ajouté une nouvelle fonctionnalité à SQL Server Management Studio, appelée Compare Showplan. Cette fonctionnalité nous permet de comparer deux plans d'exécution différents. En même temps, nous pouvons utiliser cette option hors ligne, ce qui signifie que nous n'avons pas besoin de connecter l'instance SQL Server. Imaginez que vous écrivez une requête et que cette requête fonctionne bien dans l'environnement TEST mais dans PROD (environnement de production), elle fonctionne très mal. Pour gérer ce problème, nous devons comparer les plans d'exécution. Avant cette fonctionnalité, nous avions l'habitude d'ouvrir deux SQL Server Management Studios et de mettre les plans d'exécution côte à côte, mais cette méthode était très peu pratique.
Comment comparer deux plans d'exécution ?
Dans cette démonstration, nous allons utiliser la base de données AdventureWorks et comparer deux plans d'exécution qui ont une version de modèle d'estimation de cardinalité différente et détecter cette différence avec Compare Showplan.
Dans un premier temps, nous allons ouvrir une nouvelle fenêtre de requête dans SQL Server Management Studio et cliquer sur Inclure le plan d'exécution réel puis exécutez la requête suivante.
SELECT soh.[SalesPersonID] ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName] ,e.[JobTitle] ,st.[Name] AS [SalesTerritory] ,soh.[SubTotal] ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] FROM [Sales].[SalesPerson] sp INNER JOIN [Sales].[SalesOrderHeader] soh ON sp.[BusinessEntityID] = soh.[SalesPersonID] INNER JOIN [Sales].[SalesTerritory] st ON sp.[TerritoryID] = st.[TerritoryID] INNER JOIN [HumanResources].[Employee] e ON soh.[SalesPersonID] = e.[BusinessEntityID] INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = sp.[BusinessEntityID]
Dans cette étape, nous allons enregistrer notre premier plan d'exécution. Faites un clic droit n'importe où dans le plan d'exécution et cliquez sur Enregistrer le plan d'exécution sous et enregistrez le plan d'exécution sous ExecutionPlan_CE140.sqlplan.
Nous allons maintenant ouvrir un nouvel onglet de requête dans SQL Server Management Studio et exécuter la requête ci-dessous. Dans cette requête, nous ajouterons l'indicateur de requête FORCE_LEGACY_CARDINALITY_ESTIMATION à la fin de la requête, ce qui oblige à utiliser l'ancienne version du modèle d'estimation de la cardinalité.
La tâche d'estimation de la cardinalité est de prédire combien de lignes notre requête renverra.
SELECT soh.[SalesPersonID] ,p.[FirstName] + ' ' + COALESCE(p.[MiddleName], '') + ' ' + p.[LastName] AS [FullName] ,e.[JobTitle] ,st.[Name] AS [SalesTerritory] ,soh.[SubTotal] ,YEAR(DATEADD(m, 6, soh.[OrderDate])) AS [FiscalYear] FROM [Sales].[SalesPerson] sp INNER JOIN [Sales].[SalesOrderHeader] soh ON sp.[BusinessEntityID] = soh.[SalesPersonID] INNER JOIN [Sales].[SalesTerritory] st ON sp.[TerritoryID] = st.[TerritoryID] INNER JOIN [HumanResources].[Employee] e ON soh.[SalesPersonID] = e.[BusinessEntityID] INNER JOIN [Person].[Person] p ON p.[BusinessEntityID] = sp.[BusinessEntityID] OPTION (USE HINT ('FORCE_LEGACY_CARDINALITY_ESTIMATION'));
Nous cliquerons sur Comparer Showplan et sélectionnez le plan d'exécution précédent qui a été enregistré sous ExecutionPlan_CE140.sqlplan.
L'image suivante illustre le premier écran du plan de comparaison d'exécution de SQL Server et les zones surlignées en rose définissent des opérations similaires.
Si nous cliquons sur un opérateur dans l'écran du plan d'exécution ci-dessous ou ci-dessus, SQL Server Management Studio met en évidence d'autres opérateurs similaires. Sur le côté droit du panneau, vous pouvez trouver des propriétés et des détails de comparaison des propriétés.
Dans cette étape, nous allons modifier les options d'analyse de ShowPlan et mettre en surbrillance l'opérateur ne correspondant pas. En bas de l'écran, nous pouvons voir l'Analyse Showplan panneau. Si nous décochons Mettre en surbrillance les opérations similaires et sélectionnez Surligner les opérateurs ne correspondant pas à des segments similaires, SQL Server Management Studio met en évidence l'opérateur inégalé. Après cela, cliquez sur Sélectionner les opérateurs dans le plan d'exécution ci-dessous et ci-dessus dans le panneau. SQL Server Management Studio compare les propriétés des opérateurs sélectionnés et place des signes d'inégalité sur les valeurs non identiques.
Si nous analysons cet écran plus en détail, la première chose est la version du modèle d'estimation de la cardinalité différence. La première version de requête est 70 et la seconde est 140. Cette différence affecte le Nombre estimé de lignes . La principale raison à l'origine des différents Nombre estimé de lignes est une version différente de l'estimation de la cardinalité. Ainsi, la version d'estimation de cardinalité affecte directement les métriques estimées de la requête. Pour cette comparaison de requêtes, nous pouvons conclure que la requête dont la version d'estimation de cardinalité est 140 fonctionne mieux car le nombre estimé de lignes est proche du nombre réel de lignes . Ce cas peut être clarifié à partir du tableau ci-dessous.
[identifiant de table=50 /]
Si nous voulons voir les plans d'exécution côte à côte sur le même écran, nous pouvons cliquer sur Toggle Splitter Orientation .
Nous allons maintenant faire une autre démonstration. Nous allons examiner la requête ci-dessous et comparer les plans d'exécution avant et après la création de l'index.
Lorsque nous examinons le plan d'exécution de la requête ci-dessous, il recommande de créer un index non clusterisé.
SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
Nous appliquerons l'index recommandé et réexécuterons la même requête.
CREATE NONCLUSTERED INDEX Index_NC ON [Sales].[SalesOrderDetail] ([SalesOrderDetailID]) GO SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
Dans cette dernière étape, nous comparerons les plans d'exécution.
Dans l'image ci-dessus, nous pouvons obtenir plusieurs informations sur les plans d'exécution. Mais la principale différence est l'opération logique domaine. L'un d'eux est Index Seek et un autre est Index Scan et cette différenciation des opérations conduit à des valeurs métriques estimées et réelles dissemblables. Enfin, l'opérateur Index Seek est plus performant que l'opérateur Index Scan.
Conclusion
Comme nous l'avons mentionné dans l'article, la fonctionnalité Compare Showplan offre certains avantages au développeur ou à l'administrateur de la base de données. Certains d'entre eux peuvent être comptés comme :
- Simple pour comparer la différence entre deux plans d'exécution.
- Simplicité de détection des problèmes de performances des requêtes dans différentes versions de SQL Server
- Simple pour détecter les problèmes de performances des requêtes dans différents environnements
- Clarifie simplement les modifications du plan d'exécution avant et après la création de l'index.
Références
- Estimation de la cardinalité (SQL Server)
- Guide de l'architecture de traitement des requêtes