InnoDB 统计行数的性能问题
2021-11-27 本文已影响0人
zhimin_
mysql 统计函数一般使用 count()
函数,我们常见的写法有 count(*)
,count(1)
,count(id)
, count(字段名)
。
count()
函数是个聚合函数,当数据非 NULL 时,就会累加 1。存储引擎会遍历整张表,然后把 Server 层需要的字段返回,非 NULL 时就累加 1。
所以上述几种写法:
coung(id)
需要存储引擎需要返回 id 字段给Server 层;
count(字段名)
需要存储引擎返回对应字段给 Server 层,此时如果字段没有创建索引,那InnoDB只能扫描主键索引树;
count(1)
存储引擎直接返回统计结果给 Server层;
coung(*)
存储引擎取整行数据返回给 Server 层吗?不是的,MySQL 对此做了优化,直接返回统计结果,因为整行数据肯定为非 NULL ;
性能排名:count(字段名)
< count(id)
< count(1)
≈ count(*)
所以我们一般使用 count(*)
就可以。针对没有 where 条件的 SQL 语句,其中有一个优化方法就是,当数据表很大,又没有创建二级索引的时候,我们可以选择一个较小的字段作为二级索引,这样 count(*)
就会选择扫描该二级索引树,以较少的IO次数统计出行数。
MySQL8 分层结构图
【拓展】
mysql执行过程:(这张图看着像极客时间丁奇老实的课程里面的呀)
image.png