我有两个表:
类别 - ID -parent_id
类别_产品 - 产品 ID - 类别_id
类别大约有 80 个条目,categories_products 大约 20,000 个。 我将类别与其自身以及categories_products 与此查询连接起来:
SELECT c0.id AS cat_id
FROM categories AS c0
LEFT JOIN categories AS c1 ON c0.id = c1.parent_id
LEFT JOIN categories AS c2 ON c1.id = c2.parent_id
LEFT JOIN categories_products ON
c0.id = categories_products.category_id
OR c1.id = categories_products.category_id
OR c2.id = categories_products.category_id
GROUP BY c0.id;
解释:
+------+-------------+---------------------+-------+------------------------------------+------------------------------------+---------+------------------+-------+--------------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+---------------------+-------+------------------------------------+------------------------------------+---------+------------------+-------+--------------------------------------------------------------+
| 1 | SIMPLE | c0 | index | NULL | fk_categories_parent_id | 5 | NULL | 86 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | c1 | ref | fk_categories_parent_id | fk_categories_parent_id | 5 | preview_m2.c0.id | 3 | Using index |
| 1 | SIMPLE | c2 | ref | fk_categories_parent_id | fk_categories_parent_id | 5 | preview_m2.c1.id | 3 | Using where; Using index |
| 1 | SIMPLE | categories_products | index | fk_categories_products_category_id | fk_categories_products_category_id | 4 | NULL | 25273 | Using where; Using index; Using join buffer (flat, BNL join) |
+------+-------------+---------------------+-------+------------------------------------+------------------------------------+---------+------------------+-------+--------------------------------------------------------------+
查询大约需要 1.5 秒,谁能告诉我如何改进?
最佳答案
基于@ABC 的建议:
- 删除不需要的连接
- 摆脱
LEFT
- 使用
UNION DISTINCT
而不是GROUP BY
添加括号,以防万一您在末尾添加某些内容(当它应该属于 UNION 时,它会属于最后一个 SELECT。
( SELECT c0.id AS cat_id FROM categories AS c0 JOIN categories_products ON c0.id = categories_products.category_id ) union DISTINCT ( SELECT c0.id AS cat_id FROM categories AS c0 JOIN categories AS c1 ON c0.id = c1.parent_id JOIN categories_products ON c1.id = categories_products.category_id ) union DISTINCT ( SELECT c0.id AS cat_id FROM categories AS c0 JOIN categories AS c1 ON c0.id = c1.parent_id JOIN categories AS c2 ON c1.id = c2.parent_id JOIN categories_products ON c2.id = categories_products.category_id );
为什么要提到categories_products
?它似乎没有带来任何好处。我希望这会给你相同的结果集:
SELECT id AS cat_id FROM categories;
关于Mysql多重连接对self和其他表性能的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29650475/