Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Mysql - Optimierung - mehrere group_concat &joins mit have

Schreiben Sie die Abfrage so um, dass sie WHERE verwendet statt HAVING . Denn WHERE wird angewendet, wenn MySQL eine Suche in Zeilen durchführt und Index verwenden kann. HAVING wird angewendet, nachdem Zeilen ausgewählt wurden, um bereits ausgewählte Ergebnisse zu filtern. HAVING kann absichtlich keine Indizes verwenden.
Sie können dies beispielsweise folgendermaßen tun:

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

Aktualisieren

Wir verbinden jede Tabelle zweimal.
Zuerst um zu prüfen, ob sie einen Wert enthält (Bedingung von FIND_IN_SET ).
Der zweite Join erzeugt Daten für GROUP_CONCAT um alle Produktwerte aus der Tabelle auszuwählen.

Aktualisierung 2

Wie @Matt Raines kommentierte, wenn wir keine Produktwerte mit GROUP_CONCAT auflisten müssen , wird die Abfrage noch einfacher:

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

Dadurch werden alle Produkte mit drei gefilterten Attributen ausgewählt.