2012-05-02 27 views
7

Tenemos un procedimiento almacenado en nuestra base de datos que actualiza una tabla uniendo 2 tablas en 30 columnas con una condición where. El SQL está en el formato general de:Muchas columnas UPDATE-JOIN con many-ISNULL lleva mucho tiempo?

UPDATE Target 
SET col1 = Source.col1 
INNER JOIN Source 
on 
ISNULL(Target.Col2, '') = ISNULL(Source.Col2, '') and 
ISNULL(Target.Col3, '') = ISNULL(Source.Col3, '') and 
. 
. 
. 
ISNULL(Target.Col31, '') = ISNULL(Source.Col31, '') and 

este es el plan de consulta. Guárdalo en tu PC y vuelve a abrirlo para que se escale mejor.

enter image description here

la tabla de origen tiene registros 65M, el 165M de destino. Anteriormente solía ejecutarse en unos pocos minutos. Considerando lo fea y potencialmente ineficiente que es la consulta, me parece sorprendente. Este mes funcionó durante 1,5 horas, usó el 100% del procesador y tuvimos que matarlo.

¿Alguna sugerencia de cómo improvisar la siguiente consulta y hacer que se ejecute a tiempo ...?

Tenemos índices de una sola columna en algunas de las columnas utilizadas en la condición de unión de 30 col.

Conozco la función ISNULL y la unión en 30 columnas es una locura y este es un mal diseño. No me culpes, heredé esta economía.

Lamentablemente, no hay tiempo para un rediseño. ¿Alguna sugerencia?

+4

¿Qué ha cambiado desde el último mes? –

+2

Actualice todos los valores NULL a '''', luego ejecute la consulta sin los ISNULL. Pero la pregunta de Remus es muy pertinente, ¿qué * ha * cambiado en ese período? – MatBailie

+1

¿Ha considerado volver a escribirlo como una combinación? ¿Ha considerado hacer que esas columnas no sean nulables para eliminar 60 llamadas ISNULL? –

Respuesta

5
  1. por favor una captura de pantalla del plan de ejecución estimado
  2. Sospecho que previamente la consulta utilizada una combinación hash (que debería), pero la estimación de alguna manera tiene cardinalidad que pasa ahora y se obtiene una combinación de bucle. Coloca una sugerencia de combinación hash en la consulta para ver si solucionó esto (INNER HASH JOIN). Una vez que tenemos el plan exacto, podemos decir más.
  3. Cambia la igualdad a (A1 = A2 OR (A1 IS NULL AND A2 IS NULL)). SQL Server realmente reconoce este patrón y lo convierte en un "igual exacto sin semántica nula estúpida" internamente. Puede buscar índices de esa manera incluso con valores nulos.

Si esto no ayuda, asegúrese de hacer el paso (3) y crear un índice de cobertura en col2-col31 incluyendo col1. Esto le dará una combinación de combinación que es el plan más eficiente posible en este caso. Es realmente rápido Advertencia: Esto duplicará el tamaño en disco de la tabla y ralentizará las actualizaciones.

+1

Agregué el plan.Ver mi publicación modificada. con respecto a su comentario sobre la eliminación de la función ISNULL, ¿qué sucede si A1 o A2 son nulos pero no ambos? – ChadD

+0

Sí, una sugerencia de combinación de hash arreglará esto. – usr

+0

@usr ¿Cómo agregar uno a la consulta? –

0

El DBa sugirió que sigamos la recomendación de los analistas de consulta de agregar un índice con las 30 columnas, la mayoría fueron columnas "incluidas". Esto permitió completar la consulta. El próximo mes, cuando ejecutamos, el mismo SQL de actualización que normalmente se ejecuta en 1,5 horas no se completó en 24 horas. Cuando ejecutamos las estadísticas de actualización, terminó en una hora.

Cuestiones relacionadas