2009-07-21 18 views
5

Estoy queriendo optimizar una consulta utilizando una unión como una sub consulta. Aunque no estoy seguro de cómo construir la consulta. Estoy usando MySQL 5Union as sub query MySQL

Ésta es la consulta inicial:

SELECT Parts.id 
FROM Parts_Category, Parts 
    LEFT JOIN Image ON Parts.image_id = Image.id 
WHERE 
( 
    (
     Parts_Category.category_id = '508' OR 
     Parts_Category.main_category_id ='508' 
    ) AND 
    Parts.id = Parts_Category.Parts_id 
) AND 
Parts.status = 'A' 
GROUP BY 
    Parts.id 

Lo que quiero hacer es reemplazar esta parte ((Parts_Category.category_id = '508' OR Parts_Category.main_category_id ='508') con el sindicato a continuación. De esta forma, puedo descartar la cláusula GROUP BY y usar índices de columnas rectas que deberían mejorar el rendimiento. Las tablas de categorías de piezas y partes contienen medio millón de registros cada una, por lo que cualquier ganancia sería excelente.

(
    SELECT * FROM 
    (
     (SELECT Parts_id FROM Parts_Category WHERE category_id = '508') 
     UNION 
     (SELECT Parts_id FROM Parts_Category WHERE main_category_id = '508') 
    ) 
    as Parts_id 
) 

¿Alguien puede darme una pista sobre cómo volver a escribirlo? Lo intenté durante horas, pero no puedo conseguirlo, ya que solo soy bastante nuevo en MySQL.

Respuesta

4
SELECT Parts.id 
FROM (
     SELECT parts_id 
     FROM Parts_Category 
     WHERE Parts_Category.category_id = '508' 
     UNION 
     SELECT parts_id 
     FROM Parts_Category 
     WHERE Parts_Category.main_category_id = '508' 
     ) pc 
JOIN Parts 
ON  parts.id = pc.parts_id 
     AND Parts.status = 'A' 
LEFT JOIN 
     Image 
ON  image.id = parts.image_id 

Tenga en cuenta que MySQL puede utilizar Index Merge y se puede volver a escribir la consulta como esta:

SELECT Parts.id 
FROM (
     SELECT DISTINCT parts_id 
     FROM Parts_Category 
     WHERE Parts_Category.category_id = '508' 
       OR Parts_Category.main_category_id = '508' 
     ) pc 
JOIN Parts 
ON  parts.id = pc.parts_id 
     AND Parts.status = 'A' 
LEFT JOIN 
     Image 
ON  image.id = parts.image_id 

, que será más eficiente si tiene los siguientes índices:

Parts_Category (category_id, parts_id) 
Parts_Category (main_category_id, parts_id) 
+0

, gracias nunca tanto Quassnoi. FY1 en una categoría de 62,000 filas ¡la consulta regresa alrededor de 1 segundo más rápido! – gus

+0

Creo que en su segundo ejemplo, tendría que agregar un GROUP BY Parts.id ya que no quiero los duplicados donde una parte puede aparecer en otras categorías. Esa fue la idea detrás de usar Union. Voy a comparar el rendimiento de todos modos. Gracias de nuevo. – gus

+0

GROUP BY fue necesario en el segundo ejemplo y si se agrega, me sale el mismo problema - filesort y usando temp de Explain. – gus