sql >> Databasteknik >  >> RDS >> Sqlserver

Jämför exekveringsplaner i SQL Server

Databasadministratör anstränger sig alltid för att justera SQL Server-frågeprestanda. Det första steget i att justera frågeprestanda är att analysera exekveringsplanen för en fråga. Under vissa förutsättningar kan SQL Server Query Optimizer skapa olika exekveringsplaner. Vid det här laget skulle jag vilja lägga till några anteckningar om SQL Server Query Optimizer. SQL Server Query Optimizer är en kostnadsbaserad optimerare som analyserar exekveringsplaner och bestämmer den optimala exekveringsplanen för en fråga. Det viktiga nyckelordet för SQL Server Query Optimizer är en optimal exekveringsplan som inte nödvändigtvis är den bästa exekveringsplanen. Det är därför, om SQL Server Query Optimizer försöker ta reda på den bästa exekveringsplanen för varje fråga, tar det extra tid och det skadar SQL Server Engine-prestanda. I SQL Server 2016 lade Microsoft till en ny förmåga till SQL Server Management Studio, kallad Compare Showplan. Denna funktion låter oss jämföra två olika utförandeplaner. Samtidigt kan vi använda det här alternativet offline vilket innebär att vi inte behöver ansluta SQL Server-instansen. Föreställ dig att du skriver en fråga och den här frågan fungerar bra i TEST-miljön men i PROD (produktionsmiljö) fungerar den mycket dåligt. För att hantera denna fråga måste vi jämföra genomförandeplaner. Innan den här funktionen öppnade vi två SQL Server Management Studios och förde exekveringsplaner sida vid sida, men den här metoden var väldigt obekväm.

Hur jämför man två genomförandeplaner?

I den här demonstrationen kommer vi att använda AdventureWorks-databasen och jämföra två exekveringsplaner som har olika version av Cardinality Estimation Model-versionen och upptäcka denna skillnad med Compare Showplan.

Först öppnar vi ett nytt frågefönster i SQL Server Management Studio och klickar på Inkludera faktisk exekveringsplan och kör sedan följande fråga.

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 det här steget kommer vi att spara vår första utförandeplan. Högerklicka var som helst i exekveringsplanen och klicka på Spara exekveringsplan som och spara exekveringsplanen som ExecutionPlan_CE140.sqlplan.

Nu kommer vi att öppna en ny frågeflik i SQL Server Management Studio och köra nedanstående fråga. I den här frågan kommer vi att lägga till FORCE_LEGACY_CARDINALITY_ESTIMATION-frågetipset i slutet av frågan som tvingar använda äldre version av Cardinality Estimation Model-versionen.
Uppgiften Cardinality Estimation är att förutsäga hur många rader vår fråga kommer att returnera.

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 kommer att klicka på Jämför Showplan och välj tidigare exekveringsplan som sparades som ExecutionPlan_CE140.sqlplan.

Följande bild illustrerar den första skärmen av SQL Server-exekveringsjämförelseplanen och de rosa färgmarkerade områdena definierar liknande operationer.

Om vi ​​klickar på någon operatör i exekveringsplanskärmen nedan eller ovan, framhäver SQL Server Management Studio andra liknande operatörer. På höger sida av panelen kan du hitta egenskaper och jämförelsedetaljer för egenskaper.

I det här steget kommer vi att ändra alternativen för ShowPlan Analysis och kommer att markera den operator som inte matchar. Längst ned på skärmen kan vi se Showplan Analysis panel. Om vi ​​rensar Markera liknande operationer och välj Markera operatorer som inte matchar liknande segment, SQL Server Management Studio framhäver oöverträffad operatör. Efter det klickar du på Välj operatorer i utförandeplanen nedan och ovan i panelen. SQL Server Management Studio jämför egenskaper för de valda operatörerna och sätter olikhetstecken till de icke-identiska värdena.

Om vi ​​analyserar den här skärmen mer i detalj är det första Cardinality Estimation Model Version skillnad. Den första frågeversionen är 70 och den andra är 140. Denna skillnad påverkar Uppskattat antal rader . Den främsta orsaken till det olika uppskattade antalet rader är en annan version av Cardinality Estimation. Således påverkar Cardinality Estimation-versionen direkt den uppskattade frågans mätvärden. För den här frågejämförelsen kan vi dra slutsatsen att frågan vars version av Cardinality Estimation är 140 fungerar bättre eftersom det uppskattade antalet rader är nära Faktiskt antal rader . Detta fall kan förtydligas från tabellen nedan.

[tabell id=50 /]

Om vi ​​vill se utförandeplaner sida vid sida på samma skärm kan vi klicka på Toggle Splitter Orientation .

Nu ska vi göra ännu en demonstration. Vi kommer att titta på frågan nedan och jämföra exekveringsplaner före och efter indexskapandet.
När vi tittar på exekveringsplanen nedan, rekommenderar den att du skapar ett icke-klustrat index.

SELECT [CarrierTrackingNumber] 
FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12

Vi kommer att tillämpa det rekommenderade indexet och köra samma fråga igen.

CREATE NONCLUSTERED INDEX Index_NC
ON [Sales].[SalesOrderDetail] ([SalesOrderDetailID])
GO
SELECT [CarrierTrackingNumber] 
FROM [Sales].[SalesOrderDetail] WHERE [SalesOrderDetailID]=12

I detta sista steg kommer vi att jämföra genomförandeplanerna.

I bilden ovan kan vi få flera uppgifter om genomförandeplaner. Men den stora skillnaden är den logiska operationen fält. En av dem är Indexsökning och en annan är Indexskanning och denna operationsdifferentiering leder till olika uppskattade och faktiska metriska värden. Till sist presterar Index Seek-operatören bättre än Index Scan-operatören.

Slutsatser

Som vi nämnde i artikeln erbjuder funktionen Jämför Showplan några fördelar för databasutvecklare eller administratör. Några av dessa kan räknas som:

  • Enkel skillnad att jämföra två genomförandeplaner.
  • Enkelt att upptäcka frågeprestandaproblem i olika SQL Server-versioner.
  • Enkelt att upptäcka frågeprestandaproblem i olika miljöer.
  • Förtydligar helt enkelt exekveringsplanändringar före och efter indexskapandet.

Referenser

  • Kardinalitetsuppskattning (SQL-server)
  • Frågebearbetningsarkitekturguide

  1. Snabbare sätt att infoga, via skript, i Oracle?

  2. Utarbetat uttalande om Postgresql i Rails

  3. SQL Server Error 110:Det finns färre kolumner i INSERT-satsen än de värden som anges i VALUES-satsen.

  4. Rangordna funktion i MySQL med Order By-klausul