2009-07-21 16 views
5

Sto cercando di ottimizzare una query utilizzando un unione come query secondaria. Non sono sicuro di come costruire la query. Sto usando MySQL 5Unione come interrogazione secondaria MySQL

Ecco la query originale:

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 

Quello che voglio fare è sostituire questa parte ((Parts_Category.category_id = '508' OR Parts_Category.main_category_id ='508') con l'unione di seguito. In questo modo posso abbandonare la clausola GROUP BY e utilizzare dritti col index che dovrebbero migliorare le prestazioni. Le tabelle delle parti e delle parti contengono circa mezzo milione di copie ciascuna, quindi qualsiasi guadagno sarebbe grande.

(
    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 
) 

Qualcuno può darmi un indizio su come riscriverlo? Ho provato per ore ma non riesco a ottenerlo dato che sono abbastanza nuovo in MySQL.

risposta

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 

noti che MySQL può usare Index Merge e si può riscrivere la query come questa:

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 

, che sarà più efficace se si hanno i seguenti indici:

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

Grazie di sempre così tanto Quassnoi. FY1 su una categoria di 62.000 righe la query restituisce circa 1 secondo più veloce! – gus

+0

Penso che nel tuo secondo esempio dovrei aggiungere un GROUP BY Parts.id poiché non desidero i duplicati in cui una parte possa essere elencata in altre categorie. Questa era l'idea alla base dell'uso di Union. Parlerò comunque della prestazione. Grazie ancora. – gus

+0

GROUP BY era necessario nel secondo esempio e se aggiunto ottengo lo stesso problema - filesort e usando temp da Explain. – gus

Problemi correlati