2010-04-11 8 views
10

Tengo un procedimiento almacenado bastante complejo (o feo según cómo lo mire) que se ejecuta en SQL Server 2008. Basa una gran parte de la lógica en una vista que tiene una tabla pk y una tabla fk. La tabla fk se deja unir a la tabla pk un poco más de 30 veces (la tabla fk tiene un diseño pobre; utiliza pares de valores de nombre que necesito aplanar. Desafortunadamente, es de terceros y no puedo cambiarlo).La generación del plan de consulta SQL tarda 5 minutos, la consulta misma se ejecuta en milisegundos. ¿Que pasa?

De todos modos, había estado funcionando bien durante semanas hasta que periódicamente noté una carrera que tomaría 3-5 minutos. Resulta que este es el tiempo que lleva generar el plan de consulta. Una vez que el plan de consulta existe y se almacena en caché, el procedimiento almacenado se ejecuta de manera muy eficiente. Las cosas funcionan sin problemas hasta que haya una razón para regenerar y almacenar en caché el plan de consulta nuevamente.

¿Alguien ha visto esto? ¿Por qué lleva tanto tiempo generar el plan? ¿Hay formas de hacer que surja un plan más rápido?

Respuesta

3

Puede intentar con un Plan Guide. La generación del plan aún durará algún tiempo, pero debería ser significativamente más corta.

2

¿Ha considerado volver a escribir su SELECCIÓN de 30 uniones a smth de esta manera?

SELECT [key], NULL AS [a], NULL AS [b] 
    INTO #temp 
    FROM [pk-table] 

UPDATE t SET t.[a] = fk.[a], t.[b] = fk.[b] 
    FROM #temp t 
    INNER JOIN (
    SELECT f.[key], 
     MAX(CASE WHEN f.[name] = 'a' THEN f.[value] ELSE NULL END) AS [a], 
     MAX(CASE WHEN f.[name] = 'b' THEN f.[value] ELSE NULL END) AS [b] 
    FROM [fk-table] f 
    GROUP BY f.[key] 
    ) fk ON (fk.[key] = t.[key] 

Aunque no es quizá una respuesta a su pregunta original :)

+0

Esto también vale la pena. Aunque he probado PIVOT y algunos CTE y hasta ahora la izquierda se une como una vista, ha sido la más eficiente. ¿Has visto de esta manera ser más rápido antes? – TheEmirOfGroofunkistan

+0

Sí. Tenía la misma lógica (múltiples (alrededor de 20) combinaciones a la izquierda de "tabla-fk" a una "tabla maestra"), y el tiempo de ejecución aumentó drásticamente después de agregar otra combinación de la misma tabla. Reescribir esa selección de uno gigante a uno de dos pasos realmente ayudó. Pero tal vez fue solo un caso particular de índices desafortunados, no fui a cavar. (Y lo siento, perdí la frase "en una vista" en tu publicación) –

+0

np: la vista simplemente simplifica la reutilización de la consulta, no estoy seguro de que sea necesaria. – TheEmirOfGroofunkistan

2

Algo habrá causado un plan para requerir volver a compilar como una actualización de las estadísticas o el cambio DDL. La lista si está aquí: Execution Plan Caching and Reuse

La consulta en su forma actual siempre tardará entre 3 y 5 minutos en recompilarse: esto no se puede evitar.

Suponiendo que no puede cambiarlo (PIVOT, use un disparador para mantener una tabla "adecuada", etc.), solo puede controlar cuándo ocurre la recompilación.

La respuesta de la guía de plan de Remus es de una sola vía. También vería mi mantenimiento estadístico y me aseguraré de que esté hecho durante la noche, por lo que solo ocurre una vez al inicio del día

+0

Gracias. Estoy tratando de evitar el uso de la guía del plan a menos que realmente tenga que hacerlo. Forzar estadísticas durante la noche es una buena solución. Además, pensamos en tratar de usar los factores desencadenantes. Todavía no tenemos una buena idea de la carga real sobre la mesa, ya que aún no es un sistema en vivo.Pero me gustaría probarlo. – TheEmirOfGroofunkistan

Cuestiones relacionadas