Mysql多重连接对self和其他表性能的影响

标签 mysql performance self-join

我有两个表:

类别 - 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/

相关文章:

sqlite - sqlite self 加入where子句

php - 下拉菜单回显错误

java - 是否可以使用 JpaRepository 在 Spring Data JPA 中使用 "TRUNCATE"?或者比标准 deleteAll() 更有效的方法?

mysql - 使用 2 个外键创建表在 MySQL 中不起作用

mysql - mysql-query 中有多少个 where-clause 太多了?

sql - Oracle 计数 (*) 花费太多时间

Python:将字母和数字的组合写入文件

php - 同一张表上的相关项目

SQL Server - UPDATE 语句中的 JOIN

MySQL 重用函数返回的值