Count(的设计
使用分类
- COUNT(1),COUNT(*),COUNT(常量),COUNT(主键),COUNT(ROWID),COUNT(非空列);
- COUNT(允许为空列)
- COUNT(DISTINCT 列名)
使用区别
- 1类统计结果的行数是表中所有存在的行的总数,包括值为null的行为空行。
- COUNT(允许为空列) 统计的行数不会包括字段值为null的行
- COUNT(DISTINCT 列名)得到的结果是除去值为null和重复数据后的结果
查询效率
对于COUNT(1) COUNT(*) COUNT(rowID) COUNT(常量)
- COUNT(主键)、COUNT(非空列)会首先选择主键上的索引快速全扫描(INDEX FAST FULL SCAN),若主键不存在则会选择非空列上的索引
- 若非空列上没有索引肯定会走全表扫描(TABLE ACESS FULL)
- COUNT(ROWID) 在走索引的时候比其他方式要慢
- 除了COUNT(ROWID) 其他最终都会转换为COUNT(*) 的方式执行
对于COUNT(colID),统计非NULL的行数。只要字段上有索引则会选择索引快速全扫描(INDEX FAST FULL SCAN)
- 除非列上有NOT NULL约束,否则执行计划会选择全表扫描。
count(主键ID)比count(1)慢的原因
对于 count(主键 ID) 来说,InnoDB 引擎会遍历主键索引树,把每一行的ID值取出来,返回给server层,server层拿到ID后,判断是不可能为空的,按行累加加1,最后返回累计值。
对于count(1),InnoDB引擎会扫描主键索引树,但不取值,server层对于返回的每一行,按行累计加1,判断不可能为NULL,返回累计值。
从InnoDB引擎层返回ID会涉及到解析数据行、拷贝字段值的操作,因此count(主键 ID)执行要比count(1)执行慢。
版权声明:本文为weixin_42170152原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。