Mysql
 sql >> Database >  >> RDS >> Mysql

Mysql - ottimizzazione - più group_concat e si uniscono usando avere

Riscrivi la query per utilizzare WHERE invece di HAVING . Perché WHERE viene applicato quando MySQL esegue la ricerca su righe e può utilizzare index. HAVING viene applicato dopo che le righe sono state selezionate per filtrare il risultato già selezionato. HAVING by design non può utilizzare gli indici.
Puoi farlo, ad esempio, in questo modo:

SELECT p.id, p.name, p.default_image_id, 
    GROUP_CONCAT( DISTINCT pc.colour_id ) AS product_colours, 
    GROUP_CONCAT( DISTINCT pt.tag_id ) AS product_tags, 
    GROUP_CONCAT( DISTINCT ps.tag_id ) AS product_sizes
FROM shop_products p
    JOIN shop_product_to_colours pc_test ON p.id = pc_test.product_id AND pc_test.colour_id = 18
    JOIN shop_products_to_tag pt_test ON p.id = pt_test.product_id AND pt_test.tag_id = 1
    JOIN shop_product_colour_to_sizes ps_test ON p.id = ps_test.product_id AND ps_test.tag_id = 17
    JOIN shop_product_to_colours pc ON p.id = pc.product_id
    JOIN shop_products_to_tag pt ON p.id = pt.product_id
    JOIN shop_product_colour_to_sizes ps ON p.id = ps.product_id
WHERE p.category_id =  '50'
GROUP BY p.id
ORDER BY p.name ASC

Aggiorna

Uniamo ogni tabella due volte.
Prima per verificare se contiene un valore (condizione da FIND_IN_SET ).
Il secondo join produrrà dati per GROUP_CONCAT per selezionare tutti i valori dei prodotti dalla tabella.

Aggiornamento 2

Come ha commentato @Matt Raines, se non abbiamo bisogno elenca i valori dei prodotti con GROUP_CONCAT , la query diventa ancora più semplice:

SELECT p.id, p.name, p.default_image_id
FROM shop_products p
    JOIN shop_product_to_colours pc ON p.id = pc.product_id
    JOIN shop_products_to_tag pt ON p.id = pt.product_id
    JOIN shop_product_colour_to_sizes ps ON p.id = ps.product_id
WHERE p.category_id =  '50'
    AND (pc.colour_id = 18 AND pt.tag_id = 1 AND ps.tag_id = 17)
GROUP BY p.id
ORDER BY p.name ASC

Questo selezionerà tutti i prodotti con tre attributi filtrati.