Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.4k views
in Technique[技术] by (71.8m points)

mysql group by 多列优化思路?为什么不走联合索引?

explain SELECT a, b, COUNT(*) FROM tbname
GROUP BY a, b
order by a DESC 
limit 1

ab 列已经设置联合索引, 为什么这种操作也会执行全表扫描呢?

explain SELECT a, b FROM tbname
GROUP BY a, b
order by a DESC 

去掉 COUNTlimit 则走索引没有扫描, 这是为什么呢?

这种场景有什么优化思路呢?


表结构

CREATE TABLE `tbname` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `a` INT(11) NULL DEFAULT '0',
    `b` INT(11) NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    INDEX `testkey` (`a`, `b`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

INSERT INTO `tbname` (`a`, `b`) VALUES ('1', '1');
INSERT INTO `tbname` (`a`, `b`) VALUES ('1', '1');
INSERT INTO `tbname` (`a`, `b`) VALUES ('1', '1');
INSERT INTO `tbname` (`a`, `b`) VALUES ('1', '1');
INSERT INTO `tbname` (`a`, `b`) VALUES ('1', '1');

查询1:

explain SELECT a, b, COUNT(*) FROM tbname
GROUP BY a, b
order by a DESC 
limit 1

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| ---: | --- | --- | --- | --- | --- | --- | --- | --- | ---: | ---: | --- |
| 1 | SIMPLE | tbname | N | index | testkey | testkey | 10 | N | 5 | 100.00 | Using index; Using temporary; Using filesort |

查询2:

explain SELECT a, b FROM tbname
GROUP BY a, b
order by a DESC 

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| ---: | --- | --- | --- | --- | --- | --- | --- | --- | ---: | ---: | --- |
| 1 | SIMPLE | tbname | N | range | testkey | testkey | 10 | N | 1 | 100.00 | Using index for group-by; Using temporary; Using filesort |


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

表的ddl贴出来。
两次执行的截图也出来。
一起分析一下。
第一个查询。他确实使用索引排序了。但是。count(*) 他会扫描行数来做统计。所以又走索引,又扫描了全部。这索引并不是没有意义。索引省去groupby临时排序。

第二个查询。不一定是1
image.png

再补充一个额外的问题
order by a desc 这样的话,索引只对group by有效。order不行。
因为是联合索引。你可以理解一下为啥。order by a asc 才可以
注意Extra的解释
Using index for group-by; Using temporary; Using filesort


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...