La mayoría de los planes de consulta recreados en las últimas 4 horas.

9

Tengo un problema con el rendimiento de mi base de datos de SQL Server. He encontrado esta herramienta sp_BlitzCache . Después de ejecutar el comando, obtuve esta declaración:

Tiene 92.00% de planes creados en las últimas 24 horas y 92.00% creados en las últimas 4 horas.

Si bien identifiqué el problema (usando SQL Server Profiler, verifiqué las ocurrencias de eventos de StmtRecompile), pude encontrar solo unas pocas consultas de búsqueda de texto completo que a menudo se reconstruyen. Sin embargo, las consultas de búsqueda de texto completo representan aproximadamente el 5% de todas las consultas.

¿Tiene alguna sugerencia de lo que podría causar la recreación de los planes restantes del 87%?

Tengo SQL Server 2012 (versión 11.0.6567.0).

Editar: he agregado mis contadores de rendimiento

+---------------------------+--------------------------------+--------------+
|        object_name        |          counter_name          |  cntr_value  |
+---------------------------+--------------------------------+--------------+
| SQLServer:Buffer Manager  | Background writer pages/sec    |            0 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio         |        28436 |
| SQLServer:Buffer Manager  | Buffer cache hit ratio base    |        28436 |
| SQLServer:Buffer Manager  | Checkpoint pages/sec           |      8259452 |
| SQLServer:Buffer Manager  | Database pages                 |      4434337 |
| SQLServer:Buffer Manager  | Free list stalls/sec           |            9 |
| SQLServer:Buffer Manager  | Integral Controller Slope      |            0 |
| SQLServer:Buffer Manager  | Lazy writes/sec                |         5608 |
| SQLServer:Buffer Manager  | Page life expectancy           |       438901 |
| SQLServer:Buffer Manager  | Page lookups/sec               | 122694703703 |
| SQLServer:Buffer Manager  | Page reads/sec                 |     60994608 |
| SQLServer:Buffer Manager  | Page writes/sec                |    126076564 |
| SQLServer:Buffer Manager  | Readahead pages/sec            |     45305420 |
| SQLServer:Buffer Manager  | Target pages                   |    130990080 |
| SQLServer:Buffer Node     | Database pages                 |      4434337 |
| SQLServer:Buffer Node     | Page life expectancy           |       438901 |
| SQLServer:Buffer Node     | Local node page lookups/sec    |            0 |
| SQLServer:Buffer Node     | Remote node page lookups/sec   |            0 |
| SQLServer:Memory Manager  | External benefit of memory     |            0 |
| SQLServer:Memory Manager  | Connection Memory (KB)         |         3304 |
| SQLServer:Memory Manager  | Database Cache Memory (KB)     |     35474784 |
| SQLServer:Memory Manager  | Free Memory (KB)               |     13229808 |
| SQLServer:Memory Manager  | Granted Workspace Memory (KB)  |            0 |
| SQLServer:Memory Manager  | Lock Memory (KB)               |       455928 |
| SQLServer:Memory Manager  | Lock Blocks Allocated          |      1798154 |
| SQLServer:Memory Manager  | Lock Owner Blocks Allocated    |      3568588 |
| SQLServer:Memory Manager  | Lock Blocks                    |        10562 |
| SQLServer:Memory Manager  | Lock Owner Blocks              |        10617 |
| SQLServer:Memory Manager  | Maximum Workspace Memory (KB)  |     43368000 |
| SQLServer:Memory Manager  | Memory Grants Outstanding      |            0 |
| SQLServer:Memory Manager  | Memory Grants Pending          |            0 |
| SQLServer:Memory Manager  | Optimizer Memory (KB)          |         1400 |
| SQLServer:Memory Manager  | Reserved Server Memory (KB)    |            0 |
| SQLServer:Memory Manager  | SQL Cache Memory (KB)          |       229112 |
| SQLServer:Memory Manager  | Stolen Server Memory (KB)      |      8063232 |
| SQLServer:Memory Manager  | Log Pool Memory (KB)           |         4192 |
| SQLServer:Memory Manager  | Target Server Memory (KB)      |     56934400 |
| SQLServer:Memory Manager  | Total Server Memory (KB)       |     56767824 |
| SQLServer:Memory Node     | Database Node Memory (KB)      |     35474784 |
| SQLServer:Memory Node     | Free Node Memory (KB)          |     13229808 |
| SQLServer:Memory Node     | Foreign Node Memory (KB)       |            0 |
| SQLServer:Memory Node     | Stolen Node Memory (KB)        |      8063208 |
| SQLServer:Memory Node     | Target Node Memory (KB)        |     56934376 |
| SQLServer:Memory Node     | Total Node Memory (KB)         |     56767800 |
+---------------------------+--------------------------------+--------------+
Marcin Topolewski
fuente
Tal vez alguien corrió DBCC FREEPROCCACHE? : P
Daniel Björk
@ DanielBjörk Soy la única persona que tiene permiso para hacer cosas como esta, así que no creo que sea la razón. Sin embargo, lo comprobaré.
Marcin Topolewski
¿Está utilizando consultas parametrizadas o procedimientos almacenados? ¿O el problema es que tiene literales de cadena / número en su SQL y, por lo tanto, los planes no pueden reutilizarse?
James Z
@JamesZ Sí, estoy usando muchas consultas parametrizadas. La herramienta que he mencionado en mi publicación, BlitzCache, dice que tengo un problema con la detección de parámetros.
Marcin Topolewski
1
¿Está reconstruyendo índices o actualizando estadísticas todas las noches? Tal vez hay presión de memoria en el servidor?
Erik Darling

Respuestas:

6

La consulta utilizada para probar el tiempo de creación del plan es esta

WITH x AS (
SELECT SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 24 THEN 1 ELSE 0 END) AS [plans_24],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 4 THEN 1 ELSE 0 END) AS [plans_4],
       SUM(CASE WHEN DATEDIFF(HOUR, deqs.creation_time, SYSDATETIME()) <= 1 THEN 1 ELSE 0 END) AS [plans_1],
       COUNT(deqs.creation_time) AS [total_plans]
FROM sys.dm_exec_query_stats AS deqs
)
SELECT CONVERT(DECIMAL(3,2), NULLIF(x.plans_24, 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_24],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_4 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_4],
       CONVERT(DECIMAL(3,2), NULLIF(x.plans_1 , 0) / (1. * NULLIF(x.total_plans, 0))) * 100 AS [percent_1],
       @@SPID AS SPID
INTO #plan_creation
FROM x
OPTION (RECOMPILE) ;

También el SP proporciona algunas pistas sobre dónde comenzar su investigación adicional

Si estos porcentajes son altos, puede ser un signo de presión de memoria o inestabilidad de caché plan

Aparte de las pistas anteriores, verifique si su servidor se ha reiniciado.

si su servidor no se reinicia, a continuación se muestra el enfoque que tomaría

  • compruebe si su presión de memoria enfrenta

Primero vea, si sus ajustes de memoria están configurados de manera óptima. Si es así, puede usar los contadores siguientes para ver si enfrenta presión de memoria

Memoria: Disponible MB
SQL Buffer: Free Pages
SQL Buffer: Page Life
SQL Buffer: Lazy Writes

si enfrenta presión de memoria, puede ver y ajustar las consultas que usan más memoria o intente agregar más memoria

Es posible que haya ejecutado consultas que provocan la recompilación. Algunas de ellas incluyen

  • Cambios realizados en una tabla o vista referenciada por la consulta (ALTER TABLE y ALTER VIEW).

  • Los cambios realizados en un solo procedimiento, que eliminarían todos los planes para ese procedimiento del caché (ALTER PROCEDURE).

  • Cambios en los índices utilizados por el plan de ejecución.

  • Actualizaciones sobre estadísticas utilizadas por el plan de ejecución, generadas explícitamente a partir de una declaración, como ACTUALIZAR ESTADÍSTICAS, o generadas automáticamente.

  • Descartar un índice utilizado por el plan de ejecución.

También puede ver este documento técnico para obtener más detalles sobre el almacenamiento en caché

https://technet.microsoft.com/en-us/library/ee343986(v=sql.100).aspx

TheGameiswar
fuente
He agregado mis contadores de rendimiento, ¿podría ayudarme a interpretar estos valores?
Marcin Topolewski
puede buscar contadores relacionados con la memoria detallada aquí: blogs.msdn.microsoft.com/teekamg/2007/11/06/…
TheGameiswar
@TheGameiswar dice "puede que haya ejecutado consultas que provoquen una compilación ... como cambios en el índice, actualización de estadísticas". Si indexo reorganizar / reconstruir basado en estadísticas de fragmentación + actualización todas las noches, ¿eso significa que mis planes se recrearán (o casi todos) todos los días? ¿es eso un problema?
Danielle Paquette-Harvey
2

Para agregar lo que @TheGameiswar dijo, también puede ejecutar esta consulta para ver los detalles de los planes que no se obtienen de la memoria caché.

;with
    xmlnamespaces (N'http://schemas.microsoft.com/sqlserver/2004/07/showplan' as DYN)
select
    db_name(st.dbid) as DBName
    , object_schema_name(st.objectid, st.dbid) as SchemaName
    , object_name(st.objectid, st.dbid) as ObjectName
    , ecp.objtype
    , st.text
    , qp.query_plan.value('(/DYN:ShowPlanXML/DYN:BatchSequence/DYN:Batch/DYN:Statements/DYN:StmtSimple/@RetrievedFromCache)[1]', 'varchar(100)') as RetrievedFromCache
    , qp.query_plan
into #temp
from sys.dm_exec_cached_plans ecp
    outer apply sys.dm_exec_query_plan(ecp.plan_handle) qp
    outer apply sys.dm_exec_sql_text(ecp.plan_handle) st

select
    *
from #temp t
where t.RetrievedFromCache is null
    and t.DBName is not null
order by t.DBName, t.SchemaName, t.ObjectName;
Dean Savović
fuente