Databaseadministrator gør altid en indsats for at justere SQL Server-forespørgselsydeevnen. Det første trin i tuning af forespørgselsydeevne er at analysere udførelsesplanen for en forespørgsel. På nogle betingelser kan SQL Server Query Optimizer oprette forskellige eksekveringsplaner. På dette tidspunkt vil jeg gerne tilføje nogle bemærkninger om SQL Server Query Optimizer. SQL Server Query Optimizer er en omkostningsbaseret optimering, der analyserer eksekveringsplaner og beslutter den optimale eksekveringsplan for en forespørgsel. Det væsentlige nøgleord for SQL Server Query Optimizer er en optimal eksekveringsplan, som ikke nødvendigvis er den bedste eksekveringsplan. Det er derfor, hvis SQL Server Query Optimizer forsøger at finde ud af den bedste udførelsesplan for hver forespørgsel, tager det ekstra tid, og det forårsager skade på SQL Server Engine-ydelsen. I SQL Server 2016 tilføjede Microsoft en ny evne til SQL Server Management Studio, kaldet Sammenlign Showplan. Denne funktion giver os mulighed for at sammenligne to forskellige eksekveringsplaner. Samtidig kan vi bruge denne mulighed offline, hvilket betyder, at vi ikke behøver at forbinde SQL Server-instansen. Forestil dig, at du skriver en forespørgsel, og denne forespørgsel klarer sig godt i TEST-miljøet, men i PROD (produktionsmiljø) klarer den sig meget dårligt. For at håndtere dette problem er vi nødt til at sammenligne udførelsesplaner. Før denne funktion plejede vi at åbne to SQL Server Management Studios og bringe eksekveringsplaner side om side, men denne metode var meget ubelejlig.
Hvordan sammenligner man to eksekveringsplaner?
I denne demonstration vil vi bruge AdventureWorks-databasen og sammenligne to eksekveringsplaner, som har forskellige Cardinality Estimation Model-versioner og opdage denne forskel med Compare Showplan.
Først åbner vi et nyt forespørgselsvindue i SQL Server Management Studio og klikker på Inkluder faktisk eksekveringsplan og udfør derefter følgende forespørgsel.
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]
I dette trin gemmer vi vores første udførelsesplan. Højreklik hvor som helst i udførelsesplanen, og klik på Gem eksekveringsplan som og gem udførelsesplanen som ExecutionPlan_CE140.sqlplan.
Nu åbner vi en ny forespørgselsfane i SQL Server Management Studio og udfører nedenstående forespørgsel. I denne forespørgsel tilføjer vi FORCE_LEGACY_CARDINALITY_ESTIMATION-forespørgselstippet i slutningen af forespørgslen, som tvinger til at bruge ældre version af Cardinality Estimation Model-versionen.
Opgaven Cardinality Estimation er at forudsige, hvor mange rækker vores forespørgsel vil returnere.
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'));
Vi klikker påSammenlign Showplan og vælg tidligere udførelsesplan, som blev gemt som ExecutionPlan_CE140.sqlplan.
Følgende billede illustrerer det første skærmbillede af SQL Server-udførelsessammenligningsplanen og lyserøde fremhævede områder definerer lignende operationer.
Hvis vi klikker på en operatør på nedenstående eller ovenstående skærm for udførelsesplan, fremhæver SQL Server Management Studio andre lignende operatører. På højre side af panelet kan du finde egenskaber og sammenligningsdetaljer for egenskaber.
I dette trin vil vi ændre indstillingerne for ShowPlan-analyse og fremhæve den ikke-matchende operatør. I bunden af skærmen kan vi se Showplan Analysis panel. Hvis vi fjerner Fremhæv lignende handlinger og vælg Fremhæv operatorer, der ikke matcher lignende segmenter, SQL Server Management Studio fremhæver uovertruffen operatør. Klik derefter på Vælg operatører i nedenstående og ovenstående udførelsesplan i panelet. SQL Server Management Studio sammenligner egenskaber for de valgte operatører og sætter ulighedstegn til de ikke-identiske værdier.
Hvis vi analyserer denne skærm mere detaljeret, er den første ting Cardinality Estimation Model Version forskel. Den første forespørgselsversion er 70 og den anden er 140. Denne forskel påvirker estimeret antal rækker . Hovedårsagen til det forskellige estimerede antal rækker er en anden version af Cardinality Estimation. Cardinality Estimation-versionen påvirker således de forespørgselsestimerede metrics direkte. For denne forespørgselssammenligning kan vi konkludere, at forespørgslen, hvis Cardinality Estimation-version er 140, klarer sig bedre, fordi det estimerede antal rækker er tæt på Faktisk antal rækker . Denne sag kan afklares ud fra nedenstående tabel.
[tabel id=50 /]
Hvis vi ønsker at se udførelsesplaner side om side på samme skærm, kan vi klikke på Toggle Splitter Orientation .
Nu vil vi lave endnu en demonstration. Vi vil se på nedenstående forespørgsel og sammenligne eksekveringsplaner før og efter indeksoprettelse.
Når vi ser på nedenstående forespørgselsudførelsesplan, anbefaler den at oprette et ikke-klynget indeks.
SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
Vi anvender det anbefalede indeks og udfører den samme forespørgsel igen.
CREATE NONCLUSTERED INDEX Index_NC ON [Sales].[SalesOrderDetail] ([SalesOrderDetailID]) GO SELECT [CarrierTrackingNumber] FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12
I dette sidste trin vil vi sammenligne udførelsesplanerne.
På ovenstående billede kan vi få flere oplysninger om udførelsesplaner. Men den største forskel er den logiske operation Mark. En af dem er Indekssøgning og en anden er Indeksscanning og denne operationsdifferentiering fører til uens estimerede og faktiske metriske værdier. Sidst og fremmest yder Index Seek-operatøren bedre end Index Scan-operatøren.
Konklusioner
Som vi nævnte i artiklen, tilbyder funktionen Sammenlign Showplan nogle fordele for databaseudvikler eller -administrator. Nogle af disse kan tælles som:
- Simpelt at sammenligne forskellen mellem to udførelsesplaner.
- Simpelt at opdage problemer med forespørgselsydeevne i forskellige SQL Server-versioner.
- Simpelt at opdage problemer med forespørgselsydeevne i forskellige miljøer.
- Tydeliggør ganske enkelt ændringer i eksekveringsplanen før og efter oprettelsen af indekset.
Referencer
- Kardinalitetsvurdering (SQL-server)
- Forespørgselsbehandlingsarkitekturvejledning