自记录-mysql-count函数

毋玺
2023-12-01
count对比
count(1)count(*)count(非空列)count(可以为空列)
效率(innodb引擎)1

1(建议使用)

23
是否会忽略null不会不会

count(*)

  • 会遍历全表,mysql优化后,该函数不会取值,也不会存在null,读行,累计计数返回;
  • SQL92定义的标准统计行数的语法;
  • MySQL 8.0.13开始,针对InnoDB的SELECT COUNT(*) FROM table语句,在扫表的过程中做了一些优化,注:这里的语句没有where和group by条件
  • innodb中索引氛围聚簇索引(主键索引)和非聚簇索引(非主键索引),聚簇索引的叶子节点中保存的是整行记录,而非聚簇索引的叶子节点中保存的是改行记录的主键的值,需通过主键回表获取整行记录,虽然查询中多了一道工序,但是相比来说非聚簇索引比聚簇索引小,MySQL会优先选择最小的非聚簇索引来扫描表
  • 当业务中判断是否存在时,可以考虑改用select 1 from table limit 1,让数据库查询的时候遇到一条就返回,这样效率会有所提升

count(常数)

  • 遍历全表,按行读取数据,每行计数为1,累加返回
  • 关于count(1)和count(*):MySQL官方文档中注明:InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.,由此看来效率上没有什么很大的区别

count(非空列) --count(id)

  • 遍历全表,按行读取数据(会选择最小索引树遍历,比相同情况下count字段效率更高),取每行主键id,判断该字段不可为空,累加计数,返回;

count(非空列) --count(普通非空列)

  • 遍历全表,按行读取数据,取每行该字段,判断该字段不可为空,累加计数,返回;列上没有索引时,会遍历主键索引树

count(可为空列)

  • 遍历全表,按行读取数据,取每行该字段,判断该字段是否为空,非空则累加计数,返回;
  • 列上没有索引时,会遍历主键索引树

阿里巴巴开发规范count相关

  1. 【强制】不要使用count(列名)或count(常量)来替代count(*),count(*)是SQL92定义的标准统计行数的语法,和数据库无关,跟null和非null无关。
    说明:count(*)会统计值为null的行,而count(列名)不会统计此列为null值的行
  2. 【强制】count(distinct col)计算该列除null之外的不重复行数,注意counr(dintinct col1,col2)如果其中一列全为null,那么即使另一列有不用的值,也返回为0.
  3. 【强制】当某一列的值全为null时,count(col)的返回结果为0,但sum(col)得返回结果为null,因此使用sum()时需注意NPE问题。
    正解:可以使用如下方式来避免sum的NPE问题,select ifnull(sum(col),0) from table
  4. 【强制】使用isnull()来判断是否为null值
    说明:null与任何值的直接比较都为null
    1)null<>null的返回结果是null,而不是false
    2)null = null 的返回结果是null,而不是true
    3)null <> 1的返回结果是null,而不是true
    反例:在sql语句中,如果在null前换行,影响可读性。select * from table where col1 is null  and col3 sos not null;而isnull(col)是一个整体,简洁易懂。从性能数据上分析,isnull(col)执行效率更快一些
  5. 【强制】代码中写分页查询逻辑时,若count为0应直接返回,避免执行后面的分页语句。

 类似资料: