TSQL: Buscar consultas que causan demasiadas compilaciones SQL y compilaciones SQL por separado

8

Quiero averiguar qué está causando las altas compilaciones SQL (no las recompilaciones) que estoy viendo en los contadores del monitor de rendimiento.

Aquí está mi opinión: si estoy viendo muchas compilaciones SQl, significa que las consultas en nuestro sistema no se almacenan en caché por los siguientes motivos:

  • Muchas consultas ad hoc
  • Ejecutando consultas que SQl no almacena en caché, por ejemplo:

    ACTUALIZAR table1 SET col1 = 'Cadena de más de 8000 caracteres .....' WHERE key_column = some int

  • Los planes se están agotando y se están eliminando de la memoria caché porque: la memoria caché se está quedando sin espacio o los planes no se están utilizando el tiempo suficiente.

Lo único que se acerca a la captura de inserciones de caché en el generador de perfiles es Procedimientos almacenados-> SP: CacheInserts, pero solo se ocupa de la caché de procedimientos almacenados.

Así que intenté lo siguiente para obtener consultas ad hoc:

SELECT [cp].[refcounts] -- when Refcounts becomes 0, plan is excluded from cache.
    , [cp].[usecounts] 
    , [cp].[objtype] 
    , st.[dbid] 
    , st.[objectid] 
    , st.[text] 
    , [qp].[query_plan] 
FROM sys.dm_exec_cached_plans cp     
CROSS APPLY sys.dm_exec_sql_text ( cp.plan_handle ) st     
CROSS APPLY sys.dm_exec_query_plan ( cp.plan_handle ) qp ;

Pensé que las consultas que causaron las compilaciones deberían ser las que tienen objtype = Adhoc, pero esto también podría relacionarse con las recompilaciones. Ahora tengo que ejecutar el generador de perfiles, capturar consultas que causan recompilaciones y luego eliminarlas de la lista anterior.

¿Voy en la dirección correcta?

¿Hay una sola consulta que pueda usar para lograr compilaciones SQL sin demasiado trabajo?

Recursos que me ayudaron a lograr el conocimiento anterior:

http://social.msdn.microsoft.com/Forums/en/sqldatabaseengine/thread/954b4fba-3774-42e3-86e7-e5172abe0c83 http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=143946 http: //technet.microsoft.com/en-nz/library/cc966425(en-us).aspx
http://www.sqlservercentral.com/Forums/Topic914951-360-1.aspx

Cualquier ayuda es muy apreciada.

Manjot
fuente

Respuestas:

7

No creo que pueda encontrar esto de una manera fácil, pero de todos modos es posible superarlo. Profiler ofrece muchos tipos de clases de eventos que se pueden usar para analizar el rendimiento de una consulta. Inicie una nueva sesión de Profiler y verifique los siguientes eventos:

Performance: Performance statistics
Stored Procedures: RPC:Completed
TSQL: SQL:BatchCompleted
TSQL: SQL: BatchStarting

Marque Mostrar todas las columnas y seleccione cada una de las columnas en Rendimiento: solo evento de estadísticas de rendimiento. El resto de eventos se pueden dejar con la configuración predeterminada.

A continuación, seleccione Filtros de columna y filtre por Nombre de base de datos y / o Nombre de inicio de sesión / Nombre de aplicación / Nombre de host, etc., si los conoce. El propósito es limitar el número de filas que se muestran en Profiler y concentrarse solo en sus necesidades.

A continuación, presione Ejecutar y deje que se ejecute durante un tiempo (2-3 minutos todo el tiempo que necesite). Analice los resultados mostrados principalmente en: Evento de estadísticas de rendimiento.

Si las estadísticas de rendimiento se producen con frecuencia, significa que el plan de una consulta se almacenó en caché por primera vez, se compiló, se volvió a compilar o se desalojó de PlanCache. Que yo sepa, si una consulta no tiene su plan de consulta en Plan Cache, verá 2 filas de eventos PerformanceStatistics y seguidas de SQL: BatchStarting , luego SQL: BatchCompleted . Significa que el Plan de consulta se compiló primero, se almacenó en caché y luego se inició y finalizó la consulta.

Mire las siguientes columnas en el evento Estadísticas de rendimiento:

SPID - ID of the session on which the event occurred. You can use it to identify the       
       row on SQL:BatchCompleted event which will display the SQL Query text and other  
       usefull information (Read/Writes, StartTime/EndTime)
Duration - Total time, in microseconds, spent during compilation.
EventSubClass - 0 = New batch SQL text that is not currently present in the cache.
                1 = Queries within a stored procedure have been compiled.
                2 = Queries within an ad hoc SQL statement have been compiled.
                3 = A cached query has been destroyed and the historical performance         
                    data associated with the plan is about to be destroyed.
                4 = A cached stored procedure has been removed from the cache and the  
                    historical performance data associated with it is about to be 
                    destroyed.

                5 = A cached trigger has been removed from the cache and the historical  
                    performance data associated with it is about to be destroyed.

Teniendo en cuenta el número de EventSubClass, puede averiguar qué sucedió con el Plan de consulta y tomar medidas específicas. Además, puede agregar otras columnas a Procedimientos almacenados y Clases de eventos de TSQL si está intersectado en HostName, WindowsUser u otra información del rastreo de Profiler. Además, la traza se puede almacenar en una tabla SQL, lo que hace que el análisis sea más fácil y mucho más personalizable. Aquí hay un enlace que describe más la clase de evento de estadísticas de rendimiento.

yrushka
fuente
4

Bueno, primero veamos si hay presión en el caché.

select bpool_visible from sys.dm_os_sys_info
go

Multiplique ese número por 8 para obtener la memoria en K. 75% de esto de 0-4G + 10% de esto de 4G-64G + 5% de más es el límite de presión de caché del plan . Si alcanza el 75% de este límite, SQL Server comenzará a depurar los planes del caché. Esta purga ocurre cuando se agrega un nuevo plan de consulta a la memoria caché, por lo que ese subproceso se detendrá para hacer este trabajo. La segunda cosa que puede hacer que los planes se purguen es si el número de planes excede 4 veces el número de cubos hash (una tabla hash asigna un plan_handle a un plan). Hay 10,000 en un sistema de 32 bits y 40,000 en un sistema de 64 bits.

select type, sum(pages_allocated_count) as pages_used from sys.dm_os_memory_objects 
where type in ('MEMOBJ_CACHESTOREOBJCP', 'MEMOBJ_CACHESTORESQLCP', 'MEMOBJ_CACHESTOREXPROC')
group by type
go

La decisión sobre qué purgar no se toma sobre el uso, sino sobre el costo del plan, los planes más baratos se purgan primero (costo de producción, no de ejecución). Puede ver esto si agrega las columnas original_costycurrent_cost su consulta en sys.dm_exec_cached_plans. Un plan ad-hoc comienza en 0 y se incrementa en 1 cada vez que se usa. Cuando se produce la presión de la memoria caché, SQL Server resta la mitad de cada costo, luego purga los que han alcanzado 0.

Si tiene muchos SQL ad-hoc, intente:

exec sp_reconfigure 'optimize for ad hoc workloads', 1
go
reconfigure
go

En este modo, SQL Server almacena en caché solo un "código auxiliar", de aproximadamente 300 bytes de tamaño (un plan de consulta normal tiene un mínimo de 24k), que contiene un hash y un puntero al texto SQL, la primera vez que ve una instrucción SQL particular, luego posteriormente almacena en caché el plan completo si se ejecuta nuevamente. Esto no necesariamente reducirá las compilaciones por sí solo, pero aliviará la presión de la memoria en el caché del plan.

Nota: Esto funciona en 2008, no lo probé en 2005.

Otro truco es

alter database ... set parameterization forced
go

Esto hará que SQL Server trate las constantes como parámetros, lo que puede ayudar con la función de autoparametrización que generalmente almacena en caché los planes para sentencias SQL similares. El SQL ad-hoc debe tener sus planes de consulta en caché, a menos que su servidor tenga muy poca memoria, pero esto se basa en coincidencias textuales exactas a menos que pueda parametrizarse, en cuyo caso se comporta más como una consulta preparada.

Gayo
fuente
¡Gracias! Sabía de esta opción de "parametrización forzada" pero tenía miedo de usarla. La única desventaja que puedo ver al usar esto es que llenará el caché. Estoy en lo cierto?
Manjot
3

¿Tiene muchos trabajos frecuentes de SQL Server en este cuadro? Tenga en cuenta que en 2005 las consultas de trabajo del agente NO se almacenan en caché y también pueden provocar la compilación de caché y compilaciones sql.

Mire la cantidad de planes con recuentos bajos de reutilización. Esos son tus culpables.

Algunas notas relacionadas sobre el almacenamiento en caché del plan a continuación.

http://www.sqlskills.com/BLOGS/KIMBERLY/post/Plan-cache-adhoc-workloads-and-clearing-the-single-use-plan-cache-bloat.aspx

http://www.sqlskills.com/BLOGS/KIMBERLY/post/Clearing-the-cache-are-there-other-options.aspx

Sankar Reddy
fuente
0

Este efecto se conoce como "contaminación del plan de consulta", donde muchas consultas SQL similares generan planes de ejecución separados pero equivalentes.

Las consultas ad-hoc causan sobrecarga por análisis individual, pero generalmente no consultan la contaminación del plan, ya que sus planes no se almacenan. Esto es diferente para consultas con un solo parámetro (en MS SQL Server), estas serán tratadas como una consulta parametrizada.

Hay algunos casos típicos para la contaminación del plan de consulta:

  • Consultas SQL con solo un parámetro literal codificado (como 'seleccionar id, nombre de la persona donde id = 1234')
  • especialmente si se usa con comandos / procedimientos almacenados que obligan a la base de datos a almacenar el plan de consulta, como 'sp_prepexec' o sp_executesql 'en MSSQL (creo que' ejecutar inmediatamente 'en Oracle funciona de manera similar)
  • consultas parcialmente parametrizadas, con una gran variación en los valores literales 'codificados', como 'select * from SoccerMatches sm where sm.Date>?' y sm.Date <? y HomeClubId = 5678 y GuestClubId = 1234 '. Estos guardarán planes de consulta debido a los parámetros, pero crearán un nuevo plan de consulta para cada HomeClub o GuestClub modificado (especialmente porque los valores de Fecha / Hora son una gran ocasión para introducir parámetros en muchas API de DB, cuando las consultas fallan debido a una fecha localmente diferente formatos).
  • Otra fuente de contaminación del plan de consulta puede ser marcos como ADO.NET con controladores insuficientes, en combinación con valores de cadena / (n) varchar. Algunas implementaciones / controladores establecerán los tamaños de los parámetros a la longitud real de la cadena, lo que provocará un plan de consulta separado para cada longitud de parámetro de cadena diferente en la consulta. La mejor práctica parece ser el uso del tamaño de campo máximo (por ejemplo, varchar (4000)), o un controlador que pone la longitud correcta
Erik Hart
fuente