此MySQL查询不使用我的索引

时间:2015-07-06 19:45:48

标签: mysql database

以下查询获取计算机组列表。对于每个组,它总计有多少台计算机具有state = 1以及有多少台具有state = 2

SELECT 
  cg.id
  cg.order
  cg.group_mode
  cg.created
  cg.updated
  SUM(
    CASE WHEN c.state = 1 THEN 1 ELSE 0 END
  ) AS sclr7, 
  SUM(
    CASE WHEN c.state = 2 THEN 1 ELSE 0 END
  ) AS sclr8, 
FROM 
  computer_group cg 
  LEFT JOIN computer c ON cg.id = c.group_id 
WHERE 
  cg.group_mode <> 3 
GROUP BY 
  cg.id 
ORDER BY 
  cg.order ASC;

当我在这个查询上运行EXPLAIN时,mysql返回:使用where;使用临时;使用filesort

+----+-------------+-------+------+----------------------+----------------------+---------+--------------------+------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys        | key                  | key_len | ref                | rows | filtered | Extra                                        |
+----+-------------+-------+------+----------------------+----------------------+---------+--------------------+------+----------+----------------------------------------------+
|  1 | SIMPLE      | cg   | ALL  | mode                 | NULL                 | NULL    | NULL               |   33 |   100.00 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | c    | ref  | IDX_39B3258BBE45D62E | IDX_39B3258BBE45D62E | 768     | test.c.id          |   57 |   100.00 |                                              |
+----+-------------+-------+------+----------------------+----------------------+---------+--------------------+------+----------+----------------------------------------------+

我有以下索引:

computer_group table

+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table          | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| computer_group |          0 | PRIMARY  |            1 | id          | A         |          33 |     NULL | NULL   |      | BTREE      |         |
| computer_group |          1 | mode     |            1 | mode        | A         |           3 |     NULL | NULL   |      | BTREE      |         |
| computer_group |          1 | order    |            1 | order       | A         |          33 |     NULL | NULL   |      | BTREE      |         |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

(复制/粘贴computer_group出现问题,现已修复)

电脑桌

+--------------+------------+----------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| Table        | Non_unique | Key_name             | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+--------------+------------+----------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
| computer     |          0 | PRIMARY              |            1 | id            | A         |        2611 |     NULL | NULL   |      | BTREE      |         |
| computer     |          1 | IDX_39B3258BBE45D62E |            1 | group_id      | A         |          32 |     NULL | NULL   | YES  | BTREE      |         |
| computer     |          1 | state                |            1 | state         | A         |           1 |     NULL | NULL   |      | BTREE      |         |
+--------------+------------+----------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+

我试图添加各种索引,但似乎我无法阻止filesort和临时表。

这让我疯了。我花了几天时间试图解决这个问题。我做错了什么或这是不可预防的?

1 个答案:

答案 0 :(得分:0)

如果消除外部group by

,您应该能够使用索引
SELECT cg.*, c.sclr7, c.sclr8
FROM computer_group cg JOIN
       (SELECT c.group_id, SUM(c.state = 1) as sclr7, SUM(c.state = 1) on sclr8
        FROM computer c
       ) c
       ON cg.id = c.group_id 
WHERE cg.group_mode <> 3
ORDER BY cg.order ASC;

MySQL 可能使用computer_group(order, group_mode)上的索引进行查询 join实际上可能会混淆MySQL。一个更确定的问题是:

SELECT cg.*,
       (SELECT SUM(c.state = 1)
        FROM computer c
        WHERE cg.id = c.group_id 
       ) as sclr7,
       (SELECT SUM(c.state = 2)
        FROM computer c
        WHERE cg.id = c.group_id 
       ) as sclr8
FROM computer_group cg 
     ON cg.id = c.group_id 
WHERE cg.group_mode <> 3
ORDER BY cg.order ASC;

您需要computer_group(order, group_mode, id)computer(group_id, state)上的索引。