2011-08-19 19 views
5

Recientemente tuvimos un problema de rendimiento y esto se resolvió mediante la ejecución de DBCC freeproccache ... Ahora, tenemos muchas más preguntas para responder;DBCC freeproccache?

  • Lo que hizo que la memoria caché del procedimiento fuera de fecha?
  • Si los índices o estadísticas están desactualizados, ¿por qué la consulta no se recompila ?
  • ¿Es una buena práctica programar DBCC freeproccache como TRABAJO?
  • ¿Hay alguna manera de identificar los posibles planes de consulta desactualizados?
  • ¿Hay alguna manera de identificar una consulta ofensiva?

¡Cualquier ayuda es apreciada!

+0

Identifique qué versión de SQL Server está utilizando, p. Ej. [tag: sql-server-2005], [tag: sql-server-2008] ... –

+2

Todo 'DBCC freeproccache' hace vaciar el caché del procedimiento. No hará que las estadísticas se actualicen. Por el contrario, si las estadísticas se actualizan automáticamente, el plan se volverá a compilar.Supongo que tiene un problema de detección de parámetros donde el plan que estaba en el caché para una consulta no era adecuado para todos los posibles valores de parámetros. –

+0

¡Estoy en SQL Server 2005! – user173552

Respuesta

8

Sus preguntas están por todas partes, así que trataré de abordarlas todas. El caché de procedimiento es solo tan grande. Es posible que su caché de procedimientos se haya rellenado con planes de un solo uso (esto no tiene ningún impacto en las estadísticas, aunque las estadísticas pueden afectar el caché del plan). Puede leer muchos detalles sobre los planes de un solo uso en la publicación de blog de Kimberly Tripp, "Plan cache and optimizing for adhoc workloads", incluida una consulta en contra del sys.dm_exec_cached_plans que ayudará a identificar cuándo se llena el caché con muchos planes de un solo uso. Como ella sugiere, puede evitar esta hinchazón utilizando optimizar para cargas de trabajo ad hoc. Si encuentra la necesidad de hacer esto a menudo, diría que programar freeproccache como trabajo es una curita, no una solución.

Para eliminar un plan "malo", primero debe identificar el plan "malo". Puede tratarse de un plan que excede un determinado tamaño y/o no se ha ejecutado en algún momento, o que ha identificado mediante una consulta de larga ejecución, etc. Desafortunadamente no es sencillo identificar un plan que es víctima de un parámetro olfatear a menos que ya sepas la consulta o las consultas que se ven afectadas. Supongamos que usted quiere encontrar los planes más antiguos de la memoria caché que no ha sido dirigido en más de una semana:

;WITH x AS 
(
    SELECT TOP 10 
     qs.[sql_handle], qs.plan_handle, 
     txs = qs.statement_start_offset, 
     txe = qs.statement_end_offset, 
     [size] = cp.size_in_bytes, 
     [uses] = SUM(cp.usecounts), 
     [last] = MAX(qs.last_execution_time) 
    FROM 
     sys.dm_exec_query_stats AS qs 
    INNER JOIN 
     sys.dm_exec_cached_plans AS cp 
     ON qs.plan_handle = cp.plan_handle 
    WHERE 
     qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP) 
    GROUP BY 
     qs.[sql_handle], qs.plan_handle, cp.size_in_bytes, 
     qs.statement_start_offset, qs.statement_end_offset 
    ORDER BY 
     [size] DESC 
) 
SELECT 
    x.plan_handle, 
    size, uses, [last], 
    [statement] = COALESCE(NULLIF(
     SUBSTRING(t.[text], x.txs/2, 
      CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END 
     ), ''), t.[text]) 
FROM x 
CROSS APPLY sys.dm_exec_sql_text(x.[sql_handle]) AS t; 

Ahora tiene que verificar que realmente desea borrar a cabo este plan. Por ejemplo, si reconoce esa consulta como algo que el CEO podría ejecutar mañana, tal vez sea mejor dejarla allí. Si desea borrar el plan, puede borrar directamente diciendo:

DBCC FREEPROCCACHE([paste plan handle from above query here]); 

Esto suena como mucho más trabajo que ejecuta DBCC FREEPROCCACHE a nivel mundial, pero si usted tiene una gran cantidad de buenas planes en la memoria caché, sin duda va a ser mejor para sus usuarios en general.

Aún así, esto realmente suena como una curita. Si su caché se está llenando de basura y el rendimiento va al baño hasta que libere la caché, debe buscar un nivel superior en la arquitectura, cómo se envían las consultas, etc. Este es el comportamiento que esperaría del primera iteración de LINQ2SQL, donde almacenaba en caché una versión de un plan para una consulta para cada argumento de cadena que tenía una longitud diferente. Entonces, si tuviera un parámetro de 'Enero', obtendría un plan diferente que con un parámetro de 'Febrero' porque definiría el tipo de datos como VARCHAR(7) frente a VARCHAR(8). Estoy bastante seguro de que el comportamiento es fijo, pero no sé lo suficiente sobre su entorno/aplicación para sugerir dónde buscar precisamente las "malas ideas".

+0

Sin tener en cuenta optimizar para cargas de trabajo ad hoc: esto se introdujo con SQL Server 2008. –

Cuestiones relacionadas