暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

mysql count(主键) ,count(索引) 哪个快

原创 黄江平 2021-06-07
1647

在mysql优化中,是count主键快还是count二级索引快?Mysql 版本5.7.26

我来测试一下:

1.建一张只有主键的表

CREATE TABLE sbtest1 (
id int(11) NOT NULL AUTO_INCREMENT,
k int(11) NOT NULL DEFAULT ‘0’,
c char(120) NOT NULL DEFAULT ‘’,
pad char(60) NOT NULL DEFAULT ‘’,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=latin1

2.加载数据查看表空间占用情况,大概1.4G

[root@localhost sbtest]# ll -h sbtest1*
-rw-r----- 1 root root 8.5K Jun 7 10:35 sbtest1.frm
-rw-r----- 1 root root 1.4G Jun 7 10:40 sbtest1.ibd

3.防止缓存,重启mysql, count主键耗时11秒左右。

[root@localhost node1]# ./restart
stop /root/sandboxes/all_masters_msb_5_7_26/node1
. sandbox server started

node1 [localhost:21227] {root} ((none)) > select count(id) from sbtest.sbtest1;
±----------+
| count(id) |
±----------+
| 6400000 |
±----------+
1 row in set (11.94 sec)

node1 [localhost:21227] {root} ((none)) > select * from sys.innodb_buffer_stats_by_table where object_name=‘sbtest1’;
±--------------±------------±----------±---------±------±-------------±----------±------------+
| object_schema | object_name | allocated | data | pages | pages_hashed | pages_old | rows_cached |
±--------------±------------±----------±---------±------±-------------±----------±------------+
| sbtest | sbtest1 | 1.34 GiB | 1.23 GiB | 87675 | 0 | 32314 | 6401167 |
±--------------±------------±----------±---------±------±-------------±----------±------------+

4.建二级索引,

node1 [localhost:21227] {root} ((none)) > create index idx_k on sbtest.sbtest1(k);
Query OK, 0 rows affected (7.81 sec)
Records: 0 Duplicates: 0 Warnings: 0

5.重启mysql,count二级索引耗时1秒左右

[root@localhost node1]# ./restart
stop /root/sandboxes/all_masters_msb_5_7_26/node1

node1 [localhost:21227] {root} ((none)) > select * from sys.innodb_buffer_stats_by_table where object_name=‘sbtest1’;
Empty set (0.27 sec)

node1 [localhost:21227] {root} ((none)) > select count(k) from sbtest.sbtest1;
±---------+
| count(k) |
±---------+
| 6400000 |
±---------+
1 row in set (0.86 sec)

node1 [localhost:21227] {root} ((none)) > select * from sys.innodb_buffer_stats_by_table where object_name=‘sbtest1’;
±--------------±------------±-----------±-----------±------±-------------±----------±------------+
| object_schema | object_name | allocated | data | pages | pages_hashed | pages_old | rows_cached |
±--------------±------------±-----------±-----------±------±-------------±----------±------------+
| sbtest | sbtest1 | 338.78 MiB | 313.92 MiB | 21682 | 0 | 8241 | 3799997 |
±--------------±------------±-----------±-----------±------±-------------±----------±------------+
1 row in set (0.42 sec)

为什么count二级索引比count主键要快呢?
Mysql表的主键是cluster index, cluster indexd存数据是紧密排布,Mysqlr 二级索引是只存键值和主键值。
以表数所据为例,看一下他们存数据的区别:

id name age
1 hjp 10
2 abc 15
3 cls 20
4 ddd 30
5 eee 40
6 fff 50

Cluster index 存的数据如下图
image.png

mysql二级索引存的是键值和主键值。假如name为二级索引,数据如下图:

image.png

从以上的测试可以看出,count 主键时,基本把表的数据全描了,sys.innodb_buffer_stats_by_table表的allocated字段为1.34G,和ibd文件差不多大,基本全描到缓存了。而二级索引,allocated字段为338.78 MiB,基本就是索引的大小。

总结一下:
1.mysql的二级索引count比主键快,这和索引的存储结构有关。
2.对于用主键作为询条件的SQL,用主键查询比二级索引快,主键查询少一次回表IO。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论