sql >> Base de Datos >  >> RDS >> Sqlserver

Configuraciones de ámbito de la base de datos de SQL Server y corrección automática del plan

En este artículo, examinaremos las configuraciones del ámbito de la base de datos y la corrección automática del plan de SQL Server 2017. Microsoft agregó nuevas funciones a SQL Server 2017 que mejoraron el rendimiento de las consultas.

El rendimiento de las consultas de SQL Server está relacionado con la calidad y la precisión del plan de ejecución. Cuando ejecutamos una consulta, el optimizador de consultas analiza una gran cantidad de planes de ejecución y luego decide cuál es el plan de ejecución de consulta óptimo.

Estimación de cardinalidad heredada: El Estimador de cardinalidad predice cuántas filas devolverá la consulta y determina la asignación de memoria de la consulta.

En SQL Server 2017, la versión predeterminada del modelo de estimación de cardinalidad es 14.0, pero si desea utilizar la versión anterior 7.0 del Estimador de cardinalidad, puede hacerlo cambiando la opción Estimación de cardinalidad heredada en Configuraciones de ámbito de base de datos sección.

El valor predeterminado de la estimación de cardinalidad heredada es APAGADO. Por lo tanto, si desea utilizar la versión anterior, debe activarla.

Alternativamente, puede cambiar esta propiedad en T-SQL.

ALTER DATABASE
    SCOPED CONFIGURATION  
        SET LEGACY_CARDINALITY_ESTIMATION = OFF|ON;

Sin embargo, si habilita esta configuración, afectará a todas las consultas. Como resultado, esto puede dañar el rendimiento de la consulta. Para evitar esto, puede usar la sugerencia FORCE_LEGACY_CARDINALITY_ESTIMATION.

Cuando ejecutemos esta consulta en la base de datos de WideWorldImporters, utilizará automáticamente una nueva versión de la estimación de cardinalidad.

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

FROM Sales.Orders o

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

Cuando agregamos FORCE_LEGACY_CARDINALITY_ESTIMATION a la consulta, el optimizador de consultas usará la versión anterior o más antigua de la estimación de cardinalidad.

MAXDOP : podemos establecer el grado máximo de paralelismo para una base de datos individual. Antes de que se creara esta función, solo podíamos configurar el nivel del servidor MAXDOP.

La sugerencia de consulta MAXDOP nos permite ejecutar consultas en paralelo.

ALTER DATABASE  SCOPED CONFIGURATION 
 SET MAXDOP = 4;
 GO

Análisis de parámetros: Cuando el tiempo de ejecución de una consulta cambia drásticamente y este cambio de tiempo está relacionado con el parámetro de consulta, se denomina detección de parámetros.

Ahora, crearemos un procedimiento almacenado en la base de datos AdventureWorks. Enviaremos diferentes parámetros y compararemos los planes de ejecución.

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

Como se muestra en la imagen a continuación, SQL Server genera un plan de ejecución diferente para la misma consulta. El plan de ejecución de Query Mars recomienda un índice. El parámetro de consulta cambia el plan de ejecución óptimo.

Ejecute esta consulta y observe los planes de ejecución.

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

--Query Venus
EXEC Get_OrderID_OrderQty @ProductID=897

El plan de ejecución de Query Venus es el mismo que el plan de ejecución de Query Mars. Este es el rastreo de parámetros porque el plan de ejecución en caché se compila para el plan de ejecución de Query Mars. Por este motivo, Query Venus utiliza el mismo plan de ejecución.

Ahora, deshabilitaremos el rastreo de parámetros y ejecutaremos las mismas consultas.

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

Examinemos:

El optimizador de consultas de SQL Server generó el plan de ejecución óptimo para Query Venus y Query Mars. Este enfoque proporciona el rendimiento óptimo a la consulta.

Hay algunas opciones para evitar este problema:

  • OPCIÓN(RECOMPILAR)
  • OPCIÓN (OPTIMIZAR PARA(@VARIABLE=DESCONOCIDO))

Corrección automática de planes

SQL Server 2017 incluye una nueva función llamada Corrección automática de planes. Cuando ejecutamos una consulta, el optimizador de consultas crea un plan de ejecución. Por alguna razón, el optimizador de consultas elige planes de ejecución incorrectos. Algunas de las razones son las siguientes:

  • Una consulta que no cumple con los criterios de rendimiento
  • Estadísticas desactualizadas
  • Índices inadecuados

Cuando el optimizador de consultas de SQL Server decide cambiar el plan de ejecución y este plan de ejecución daña el rendimiento, el rendimiento de la consulta se denomina regresión del plan. Una nueva función viene con SQL Server 2016. Esta herramienta ayuda a monitorear y solucionar problemas de rendimiento de consultas y, al mismo tiempo, almacena métricas de rendimiento y contadores de la ejecución de consultas.

Podemos habilitar estas opciones en las propiedades de la base de datos.

Ahora, vamos a hacer una demostración de esta función. En primer lugar, borre la caché de procedimientos y cree un procedimiento almacenado.

/****************************************
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

En este paso, ejecutaremos este procedimiento con diferentes parámetros y encontraremos la diferencia de tiempo de ejecución.

--Query Alpha
DBCC FREEPROCCACHE 
EXEC Test_CoddingSight2 7
GO 80

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

Como puede ver, la primera consulta se completó en 12 segundos, mientras que la segunda se realizó en 33 segundos. El motivo de esta gran diferencia es que el optimizador de consultas elige un plan de ejecución inadecuado para Query Beta.

Comparemos los planes de ejecución de Query Alpha y Query Beta.

Plan de ejecución de Query Alpha

Plan de ejecución de Query Beta

En las imágenes de arriba, el optimizador de consultas crea diferentes planes de ejecución para la misma consulta. Cuando observamos las consultas que más consumen recursos , podemos ver que Query Beta consume más recursos que Query Alpha.

La siguiente consulta devolverá información detallada sobre las recomendaciones de ajuste.

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'

La columna de razones muestra por qué tenemos que aplicar esta recomendación.

Ahora, volveremos a ejecutar Query Alpha y Query Beta con la corrección automática del plan habilitada.

/****************************************
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

Después de esta demostración, el plan de ejecución de Query Alpha se aplica a Query Beta. Además, los tiempos de ejecución de Query Alpha y Query Beta son similares. La siguiente consulta devolverá el estado de corrección automática del 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')
                WITH (  query_id int '$.queryId',
                        regressed_plan_id int '$.regressedPlanId',
                        last_good_plan_id int '$.recommendedPlanId') as details
WHERE JSON_VALUE(state, '$.currentValue') = 'Verifying'

Además, podemos encontrar información gráfica en Consultas con Planes Forzados . Este gráfico define los planes de consulta forzada y la consulta.

Referencias

Corrección automática de planes en SQL Server 2017

Estimación de Cardinalidad