select count()效率比较和分析

在数据库查询优化中,看到有人说Count(*)比count(1)快。

猜测是与索引选取的列有关,对比查看执行过程,一试便知。


首先明确一点,执行时只会使用一个索引

测试结论如下:

  • count(*)和count(1)无任何差别永远优于count其他字段,无论加不加任何索引
  • count()里面的值可取任意值,与结果无关
  • 加索引显著快于不加索引
  • 主键索引快于普通索引
  • 没有索引时,与列含不含空值无关
  • count选取的列上如果有就用自己的索引,没有则使用默认索引
    (取首个添加的索引,即使存在主键

总结:

只要存在普通索引,count就会使用普通索引,

只存在主键时,count(*)和或ount(1)会使用主键索引,其他字段不会

count(*)和或ount(1)最快


配置

版本:mysql-5.7.23-winx64
CPU:Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz

经多次测试发现用mysql和navicat 效率几乎相同,故采用navicat

这里写图片描述
这里写图片描述
查询500000条数据,


Tips:

  • id字段均不为null
  • test字段均为null

1.没有主键和任何索引

select count(*) from user

OK
时间: 0.24s

select count(1) from user

OK
时间: 0.24s

select count(id) from user

OK
时间: 0.266s

select count(test) from user

OK
时间: 0.265s

多次测试结果均相同

这里写图片描述

查看执行过程,全表扫描

结论1:

不加任何索引情况下

  • count(*)和count(1)无差别
  • 查询速度和count的列是否有空值无关
  • count(列)速度慢于count(*)和count(1)

2.只有id主键

select count(*) from user

OK
时间: 0.146s

select count(1) from user

OK
时间: 0.145s

select count(id) from user

OK
时间: 0.158s

select count(test) from user

OK
时间: 0.162s

多次测试结果均相同

这里写图片描述

除了test,都使用了主键索引

结论2:

只使用主键情况下

  • 整体查询速度均有所提升
  • count(*)和count(1)无差别
  • 查询速度和count的列是否有空值有关
  • count(列)速度慢于count(*)和count(1)

3.只有索引

select count(*) from user

OK
时间: 0.234s

select count(1) from user

OK
时间: 0.233s

select count(id) from user

OK
时间: 0.247s

select count(test) from user

OK
时间: 0.268s

多次测试结果均相同

这里写图片描述

除了test,都使用了id的索引

结论3:

只有索引情况下

  • 和无索引相比,count(*)和count(1)和加索引的列速度提升
  • 但慢于主键
  • count(*)和count(1)无差别
  • 查询速度和count的列是否有空值有关
  • count(列)速度慢于count(*)和count(1)

4.同时存在主键和索引

select count(*) from user

OK
时间: 0.122s

select count(1) from user

OK
时间: 0.121s

select count(id) from user

OK
时间: 0.134s

select count(test) from user

OK
时间: 0.14s

多次测试结果均相同
这里写图片描述

全部使用自定义索引,而没有使用主键索引

结论4:

同时存在主键和索引情况下

  • 整体速度最快
  • count(*)和count(1)无差别
  • 查询速度和count的列是否有空值有关
  • count(列)速度慢于count(*)和count(1)

总结

  • count(*)和count(1)无任何差别永远优于其他count,无论加不加任何索引
  • 加索引显著快于不加索引
  • 主键索引快于普通索引
  • 没有索引时,与列含不含空值无关

其他问题1,存在多个索引怎么决定用哪个呢?

实验得知

加多个索引时,count(列),如果存在就用自己的索引
不存在则使用默认索引,按测试结果是默认的索引添加顺序。

猜你喜欢

转载自blog.csdn.net/moni_mm/article/details/82056021
今日推荐