我有一个具有以下结构的表,几乎有 120000 行,
desc user_group_report
+------------------+----------+------+-----+-------------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+----------+------+-----+-------------------+-------+
| user_id | int | YES | MUL | NULL | |
| group_id | int(11) | YES | MUL | NULL | |
| type_id | int(11) | YES | | NULL | |
| group_desc | varchar(128)| NO| | NULL |
| status | enum('open','close')|NO| | NULL | |
| last_updated | datetime | NO | | CURRENT_TIMESTAMP | |
+------------------+----------+------+-----+-------------------+-------+
我在以下键上有索引:
- user_group_type(user_id,group_id,group_type)
- group_type(group_id,type_id)
- user_type(user_id,type_id)
- 用户组(用户 ID,组 ID)
我的问题是我正在按 group_id 在上面的表组上运行 count(*) 聚合,并且在 type_id 上有一个子句
这是查询:
select count(*) user_count, group_id
from user_group_report
where type_id = 1
group by group_id;
这是解释计划(查询平均需要 0.3 秒):
+----+-------------+------------------+-------+---------------------------------+---------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+-------+---------------------------------+---------+---------+------+--------+--------------------------+
| 1 | SIMPLE | user_group_report | index | user_group_type,group_type,user_group | group_type | 10 | NULL | 119811 | Using where; Using index |
+----+-------------+------------------+-------+---------------------------------+---------+---------+------+--------+--------------------------+
在这里,据我了解,由于索引复杂,查询几乎会进行全表扫描,并且当我尝试在 group_id 上添加索引时,解释计划中的行显示的数量较少(几乎是行的一半),但查询执行所需的时间增加到 0.4-0.5 秒。
我尝试了不同的方法来添加/删除索引,但它们都没有减少所花费的时间。
假设表结构不能更改并且查询独立于其他表,有人可以建议我一种更好的方法来优化上述查询,或者如果我在这里遗漏任何东西。
PS:我已经尝试将查询修改为以下但找不到任何改进。
select count(user_id) user_count, group_id
from user_group_report
where type_id = 1
group by group_id;
任何一点帮助表示赞赏。
编辑:
根据建议,我添加了一个新索引
type_group on (type_id,group_id)
这是新的解释计划。解释中的行数,减少但查询执行时间仍然相同
+----+-------------+------------------+------+---------------------------------+---------+---------+-------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------------------------+---------+---------+-------+-------+--------------------------+
| 1 | SIMPLE | user_group_report | ref | user_group_type,type_group,user_group | type_group | 5 | const | 59846 | Using where; Using index |
+----+-------------+------------------+------+---------------------------------+---------+---------+-------+-------+--------------------------+
编辑 2: 按照答案/评论中的建议添加详细信息
select count(*)
from user_group_report
where type_id = 1
此查询本身需要 0.25 秒才能执行。
这是解释计划:
+----+-------------+------------------+------+---------------+---------+---------+-------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------------+------+---------------+---------+---------+-------+-------+-------------+
| 1 | SIMPLE | user_group_report | ref | type_group | type_group | 5 | const | 59866 | Using index |
+----+-------------+------------------+------+---------------+---------+---------+-------+-------+-------------+