Necesita acelerar esta consulta en SQL Server

votos
1
SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON pe.prodtree_element_id = pl.to_prodtree_node_id
    LEFT JOIN line li
        ON pe.line_code = li.line_code
    INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 
    LEFT JOIN attribute_values av2
        ON pe.prodtree_element_id = av.prodtree_element_id
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

# statusCode # es una identificación estática que coincide con una identificación en la tabla de definición de atributos (digamos 22 por el bien del argumento). El problema es que la consulta tiene algunos problemas graves para finalizar en cualquier cantidad de tiempo. El problema más grande es que necesito que termine antes, pero el número de registros es enorme y tiene que retroceder (alrededor de 30-50,000). Necesito datos de varias tablas, que es donde comienza a disminuir la velocidad. Esto es solo una parte de lo que necesito, también necesito otras tablas con valor de datos que coincidan con el actual prodtree_elment_id.

Estoy usando ColdFusion, pero incluso ejecutar la consulta directamente en SQL Server 2005 crea la espera de 15-30 minutos para esta consulta (si es que termina). ¿Hay alguna manera concebible de acelerar esta consulta para tomar como máximo 5 minutos o menos?

Publicado el 09/12/2008 a las 20:54
fuente por usuario
En otros idiomas...                            


6 respuestas

votos
9

INNER JOIN attribute_values av
    ON av.attribute_definition_id = #statusCode# 
LEFT JOIN attribute_values av2
    ON pe.prodtree_element_id = av.prodtree_element_id

Este es el problema. Hay una combinación cruzada entre pe y av, seguida de una combinación externa en la unión cruzada. Tienes suerte, solo toma 30 minutos :-)

Creo que quieres esto:

SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
FROM prodtree_element pe
LEFT JOIN prodtree_link pl
    ON pe.prodtree_element_id = pl.to_prodtree_node_id
LEFT JOIN line li
    ON pe.line_code = li.line_code
--replacement
LEFT JOIN
attribute_values av 
         ON pe.prodtree_element_id = av.prodtree_element_id AND
         av.attribute_definition_id = #statusCode# 
--end replacement
WHERE pe.prodtree_element_func_type <> 'WIZARD'
    AND pe.prodtree_element_topo_type = 'NODE'
Respondida el 09/12/2008 a las 21:05
fuente por usuario

votos
0
SELECT pe.prodtree_element_id prodID, pe.prodtree_element_name_s, li.line_name, av2.value
    FROM prodtree_element pe
    LEFT JOIN prodtree_link pl
        ON (pe.prodtree_element_id = pl.to_prodtree_node_id)
    LEFT JOIN line li
        ON (pe.line_code = li.line_code)
    LEFT JOIN attribute_values av2
        ON (pe.prodtree_element_id IN (SELECT av.prodtree_element_id FROM attribute_values av WHERE av.attribute_definition_id = #statusCode#))
    WHERE pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

gbn lo clavé, creo. Aunque restrinja INNER JOIN a attribute_values ​​a un valor específico, aún no está unido a su tabla primaria ni a sus relaciones. Entonces, incluso si está obteniendo resultados de la consulta, creo que hay demasiados.

Dependiendo de lo que pretendía y de cómo están sus datos en la tabla attribute_values, su consulta o la mía probablemente sería más rápida.

Respondida el 09/12/2008 a las 21:15
fuente por usuario

votos
0

asegúrese de que todas sus identificaciones sean índices también si puede asignar lo siguiente:

pe.prodtree_element_func_type <> 'WIZARD'
        AND pe.prodtree_element_topo_type = 'NODE'

ser algo así como

pe.prodtree_element_func_type_ID <> 1
            AND pe.prodtree_element_topo_type_ID = 2

para reducir las comparaciones de cadenas que toma más tiempo para completar

Respondida el 09/12/2008 a las 21:07
fuente por usuario

votos
0

Puede buscar millones de registros en pocos segundos con una buena optimización. Aunque StingyJack tiene razón en eso sin conocer el DDL, la optimización de cualquier consulta es difícil.

Sin embargo, las cosas que se deben hacer al optimizar una consulta es mirar el plan de ejecución. Los bucles anidados y similares son malos. También asegúrese de que esté completamente indexado también. Usted no menciona nada de los índices de las tablas en cuestión. Sin índices 30 - 50k filas podrían tomar un tiempo con esa cantidad de combinaciones.

Respondida el 09/12/2008 a las 21:06
fuente por usuario

votos
0

Lo primero que le sugiero es que lo ejecute a través de la utilidad del optimizador sql en el administrador de empresa siempre que lo tenga instalado. Por lo general, sugiere índices y cosas así que podrían tener un impacto positivo en la velocidad de consulta.

Otras cosas a considerar serían dividir la consulta. Desde las miradas iniciales, parece que está leyendo todos los elementos del producto que tienen un atributo particular que coincide con el valor que le da (o algo así). Yo sugeriría tal vez:

select * from [bigLongjoin to producttree_element]
where prodtree_element_id
in(
select prodtree_element_id from 
  attribute_values where attribute_definition_id = #statusCode#)

Ejecutarlo en el administrador de la empresa con el plan de consulta que se muestra también puede mostrarle dónde están los cuellos de botella

Respondida el 09/12/2008 a las 21:03
fuente por usuario

votos
0

Sin saber el DDL es muy difícil de probar. Las filas de 30-50K aún deberían tomar solo unos segundos.

Intente cambiar el orden de la cláusula where. Probablemente deberías haber implementado esto

 INNER JOIN attribute_values av
        ON av.attribute_definition_id = #statusCode# 

en la cláusula where

Respondida el 09/12/2008 a las 21:01
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more