文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

select count(?) from t之间的性能有什么差别

2024-04-02 19:55

关注

这篇文章主要介绍“select count(?) from t之间的性能有什么差别”,在日常操作中,相信很多人在select count(?) from t之间的性能有什么差别问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”select count(?) from t之间的性能有什么差别”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

在开发中,我们一定经常遇到需要统计表总记录的时候,在 select count(?) from t 这样的查询语句里面,count(*)、count(主键  id)、count(字段) 和 count(1) 该怎么选择呢?

阿里巴巴开发规约其中MySQL规约中,有4条都在规范count的用法,我们查看其中的一条:

【强制】不要使用count(列名)或count(常量)来替代count(*),  count(*)就是SQL92定义的标准统计行数的语法,跟数据库无关,跟NULL和非NULL无关。

说明:count(*)会统计值为NULL的行,而count(列名)不会统计此列为NULL值的行。

那么今天我们就来聊聊这几种不同的统计方式是怎么实现的,他们之间的性能差别是什么。

count()函数

首先我们需要了解count() 的语义。

count()是一个聚合函数,对于返回的结果集,一行行的判断,如果count函数的参数不是null,累计值就加1,否则不加。最后返回累计值。如果没有则返回0。

count(*)、count(主键 id) 和 count(1) 都表示返回满足条件的结果集的总行数;而  count(字段),则表示返回满足条件的数据行里面,参数“字段”不为null的总个数。

接下来我们具体分析每种统计方式的性能差别。

count(*)

我们在分析一条SQL语句的实现时,一定不能脱离存储引擎,在不同的MySQL存储引擎中,count(*)有不同的实现。

这个时候你是不是在想,MySQL建表时的存储引擎已经默认为InnoDB了,而且很多MySQL相关的书籍中也提到不是特别场景的必要,就使用InnoDB。

但是我们在使用count(*)做统计的时候随着表记录的增加效率会越来越慢,InnoDB怎么就不能跟MyISAM一样也把总记录数提前存储起来呢?

这里主要的一个原因是InnoDB是支持事务的,由于MVCC的原因,InnoDB表在某个时刻应该返回多少行是不确定的,它必须根据当前的事务隔离级别判断某一个记录对于当前事务是否可见。

虽然InnoDB是需要一行一行的统计,但是MySQL也是做了优化的。通过前面索引文章介绍的知识我们了解到,InnoDB分为主键索引树和普通索引树,普通索引树的叶子节点是主键值而不是行记录。所以,普通索引树要比主键索引树小很多,所以count(*)在遍历索引树的时候会找最小的那棵树来遍历。

在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

count(*)也并不会把全部字段取出来,而是做了优化,不取值。

count(*)的参数肯定不是null,按行累加之后返回结果。

count(主键 id)

count(主键 id)  ,InnoDB引擎会遍历整张表,把每一行的id值取出来,传给server层。server层拿到引擎给的id值后,判断是不可能为空的,就按行累加。

count(1)

count(1),InnoDB引擎遍历整张表,但是不取值。server层对于返回的每一行存放一个数字1,判断是不可能为空过的,按行累加。

count(字段)

而对于count(字段)字段来说,我们需要分两种情况分析参数字段。

如果这个参数字段是不允许为null(not null)的,那么InnoDB引擎则一行行地从记录里面读取这个字段,判断不能为null,则按行累加。

如果这个参数字段是允许为null的,那么执行的时候,判断到可能是null的时候还要把值取出来再判断一次,不是null才累加。

小结

count(字段)和count(主键 id)因为需要从引擎中返回值,会涉及到解析数据行以及拷贝字段的操作,性能上差于其他两种。

而count(字段)还需要判断字段参数是否为null,多了判断的操作,性能上会差于count(主键 id)。

count(1)和count(*)都不会涉及到取值,性能上差别不大。

所以结论就是,按照查询效率排名结果如下:

count(字段)<count(主键 id)<count(1)&asymp;count(*)。

按照开发规范,建议尽量使用count(*)。

到此,关于“select count(?) from t之间的性能有什么差别”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯