sql >> Database >  >> RDS >> Sqlserver

Configuraties met SQL Server-databasebereik en automatische plancorrectie

In dit artikel zullen we Database Scoped Configurations en SQL Server 2017 Automatic Plan Correction onderzoeken. Microsoft heeft nieuwe functies toegevoegd aan SQL Server 2017 die de queryprestaties hebben verbeterd.

De prestaties van SQL Server-query's zijn gerelateerd aan de kwaliteit en nauwkeurigheid van het uitvoeringsplan. Wanneer we een query uitvoeren, analyseert de query-optimizer veel uitvoeringsplannen en beslist vervolgens over het optimale uitvoeringsplan voor query's.

Verouderde kardinaliteitsschatting: De Cardinality Estimator voorspelt hoeveel rijen de query zal retourneren en bepaalt ook de geheugentoewijzing van de query.

In SQL Server 2017 is de standaardversie van het kardinaliteitsschattingsmodel 14.0, maar als u de oudere versie 7.0 van de kardinaliteitschatter wilt gebruiken, kunt u dit doen door de optie Legacy Cardinality Estimation te wijzigen in de Database Scoped Configurations sectie.

De standaardwaarde van de oude kardinaliteitsschatting is UIT. Dus als u de oudere versie wilt gebruiken, moet u deze op AAN zetten.

U kunt deze eigenschap ook wijzigen in T-SQL.

ALTER DATABASE
    SCOPED CONFIGURATION  
        SET LEGACY_CARDINALITY_ESTIMATION = OFF|ON;

Als u deze instelling echter inschakelt, heeft dit invloed op alle query's. Als gevolg hiervan kan dit de prestaties van de query schaden. Om dit te voorkomen, kun je de FORCE_LEGACY_CARDINALITY_ESTIMATION hint gebruiken.

Wanneer we deze query uitvoeren in de WideWorldImporters-database, wordt automatisch een nieuwe versie van de kardinaliteitsschatting gebruikt.

SELECT
    [o].[CustomerID],
    o.LastEditedBy ,
    [o].[OrderDate]
    

FROM Sales.Orders o

WHERE [o].[OrderDate] >= '20140101'

Wanneer we FORCE_LEGACY_CARDINALITY_ESTIMATION aan de query toevoegen, gebruikt de query-optimizer de vorige of oudste versie van de schatting van de kardinaliteit.

MAXDOP : we kunnen de maximale mate van parallellisme instellen voor een individuele database. Voordat deze functie was gemaakt, konden we alleen het MAXDOP-serverniveau configureren.

Met de MAXDOP-queryhint kunnen we query's parallel uitvoeren.

ALTER DATABASE  SCOPED CONFIGURATION 
 SET MAXDOP = 4;
 GO

Parametersnuiven: Wanneer de uitvoeringstijd van een query drastisch verandert en deze tijdswijziging is gerelateerd aan de queryparameter, wordt dit parameter sniffing genoemd.

Nu gaan we een opgeslagen procedure maken in de AdventureWorks-database. We sturen verschillende parameters en vergelijken uitvoeringsplannen.

DROP PROCEDURE IF EXISTS Get_Orders
GO
CREATE PROCEDURE Get_Orderes
@ProductID INT
AS
SELECT SalesOrderDetailID, OrderQty
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductID;

GO
/*******
Don t use this script in production servers!
*******/
DBCC FREEPROCCACHE
--Query Mars
EXEC Get_OrderID_OrderQty @ProductID=870
DBCC FREEPROCCACHE
--Query Venus
EXEC Get_OrderID_OrderQty @ProductID=897

Zoals in de onderstaande afbeelding wordt weergegeven, genereert SQL Server een ander uitvoeringsplan voor dezelfde query. Het uitvoeringsplan van Query Mars beveelt een index aan. De queryparameter verandert het optimale uitvoeringsplan.

Voer deze query uit en bekijk de uitvoeringsplannen.

DBCC FREEPROCCACHE
--Query Mars
EXEC Get_OrderID_OrderQty @ProductID=870

--Query Venus
EXEC Get_OrderID_OrderQty @ProductID=897

Het uitvoeringsplan voor Query Venus is hetzelfde als het uitvoeringsplan voor Query Mars. Dit is de parameter sniffing omdat het uitvoeringsplan in de cache is samengesteld voor het uitvoeringsplan van Query Mars. Daarom gebruikt Query Venus hetzelfde uitvoeringsplan.

Nu zullen we het snuiven van parameters uitschakelen en dezelfde zoekopdrachten uitvoeren.

ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SNIFFING =OFF;
DBCC FREEPROCCACHE
--Query Mars
EXEC Get_OrderID_OrderQty @ProductID=870

--Query Venus
EXEC Get_OrderID_OrderQty @ProductID=897

Laten we eens kijken:

De SQL Server Query-optimizer genereerde het optimale uitvoeringsplan voor Query Venus en Query Mars. Deze benadering zorgt voor de optimale prestatie van de query.

Er zijn enkele opties om dit probleem te vermijden:

  • OPTIE(OPNIEUW COMPILEREN)
  • OPTIE (OPTIMALISEREN VOOR(@VARIABLE=UNKNOWN))

Automatische plancorrectie

SQL Server 2017 bevat een nieuwe functie genaamd Automatic Plan Correction. Wanneer we een query uitvoeren, maakt de query-optimizer een uitvoeringsplan. Om bepaalde redenen kiest de query-optimizer verkeerde uitvoeringsplannen. Enkele van de redenen zijn als volgt:

  • Een zoekopdracht die niet aan de prestatiecriteria voldoet
  • Verouderde statistieken
  • Ongeschikte indexen

Wanneer de query-optimizer van SQL Server besluit het uitvoeringsplan te wijzigen en dit uitvoeringsplan de prestaties schaadt, wordt de queryprestatie de planregressie genoemd. Een nieuwe functie wordt geleverd met SQL Server 2016. Deze tool helpt bij het bewaken en oplossen van problemen met de prestaties van query's en slaat tegelijkertijd prestatiestatistieken en tellers van de uitvoering van de query op.

We kunnen deze opties inschakelen onder database-eigenschappen.

Nu gaan we een demo maken van deze functie. Maak eerst de procedurecache leeg en maak een opgeslagen procedure.

/****************************************
Don t use this script in production servers
*****************************************/

USE WideWorldImporters
ALTER DATABASE WideWorldImporters SET QUERY_STORE = ON;  
ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALL
DBCC FREEPROCCACHE  --This command will clear all procedure cache in SQL Server. Dont try in 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
 where o.PackageTypeID = @Id

Bij deze stap zullen we deze procedure met verschillende parameters uitvoeren en het verschil in uitvoeringstijd vinden.

--Query Alpha
DBCC FREEPROCCACHE 
EXEC Test_CoddingSight2 7
GO 80

DBCC FREEPROCCACHE 
EXEC Test_CoddingSight2 -1
--Query Beta
EXEC Test_CoddingSight2 7
GO 80

Zoals u kunt zien, werd de eerste zoekopdracht in 12 seconden voltooid, terwijl de tweede in 33 seconden werd voltooid. De reden voor dit dramatische verschil is dat de query-optimizer een ongeschikt uitvoeringsplan voor Query Beta kiest.

Laten we de uitvoeringsplannen van Query Alpha en Query Beta vergelijken.

Uitvoeringsplan van Query Alpha

Uitvoeringsplan van Query Beta

In de bovenstaande afbeeldingen maakt de query-optimizer verschillende uitvoeringsplannen voor dezelfde query. Als we kijken naar Topbronnen die zoekopdrachten verbruiken , kunnen we zien dat Query Beta meer bronnen verbruikt dan Query Alpha.

De onderstaande zoekopdracht levert gedetailleerde informatie op over de afstemmingsaanbevelingen.

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') as details
WHERE JSON_VALUE(state, '$.currentValue') = 'Active'

De redenkolom laat zien waarom we deze aanbeveling moeten toepassen.

Nu zullen we Query Alpha en Query Beta opnieuw uitvoeren met de automatische plancorrectie ingeschakeld.

/****************************************
Don't use this script in production servers
*****************************************/

ALTER DATABASE [WideWorldImporters] SET QUERY_STORE CLEAR ALL
DBCC FREEPROCCACHE  

/****************************************
Enable Automatic Plan Correction
*****************************************/


ALTER DATABASE WideWorldImporters SET AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN = ON); 

--Query Alpha
DBCC FREEPROCCACHE 
EXEC Test_CoddingSight2 7
GO 80


DBCC FREEPROCCACHE 
EXEC Test_CoddingSight2 -1
--Query Beta
EXEC Test_CoddingSight2 7
GO 80

Na deze demo wordt het uitvoeringsplan Query Alpha toegepast op de Query Beta. Bovendien liggen de uitvoeringstijden van Query Alpha en Query Beta dicht bij elkaar. De onderstaande vraag retourneert de automatische plancorrectiestatus.

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')
                WITH (  query_id int '$.queryId',
                        regressed_plan_id int '$.regressedPlanId',
                        last_good_plan_id int '$.recommendedPlanId') as details
WHERE JSON_VALUE(state, '$.currentValue') = 'Verifying'

We kunnen ook wat grafische informatie vinden in Queries with Forced Plans . Deze grafiek definieert de geforceerde zoekopdrachten en zoekopdrachten.

Referenties

Automatische plancorrectie in SQL Server 2017

Kardinaliteitsschatting


  1. Voorloop- en volgtekens verwijderen in MySQL

  2. Groepeer zoekopdrachtresultaten per maand en jaar in postgresql

  3. Hoe een enkele SQL Server-verbindingsinstantie open te houden voor meerdere aanvragen in C#?

  4. SQL Server:hoe orakel na te bootsen om de vraag met dichte_rank te behouden?