一. 结论

首先说一下结论,count(*)、count(1)或者是count(1000)在InnoDB储存引擎中没有性能区别。MySQL5.5之后默认使用InnoDB。

自行创建一张表,写入数据去执行上述不同 expr 的count(expr)函数后,可以验证这个结论。

但大家能看到这篇博客,肯定是厌倦了百度出的结果各种重复抄袭、表达模糊,试图找到一篇不一样的、能展开说明的博客。这里重点通过MySQL Document version5.7对count()函数进行理论说明。

二. 理论支撑

Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement. The result is a BIGINT value.

If there are no matching rows, COUNT() returns 0.

count(expr) 通过 SELECT语句查找满足表达式 expr 的非空数据行数,以bigint类型返回。

如果没有满足条件的行,count()返回0.

COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.

当 * 作为表达式传入count()函数时,count()函数将返回所有检索到的行数,无论行中存不存在NULL值。

For transactional storage engines such as InnoDB, storing an exact row count is problematic. Multiple transactions may be occurring at the same time, each of which may affect the count.

InnoDB does not keep an internal count of rows in a table because concurrent transactions might “see” different numbers of rows at the same time. Consequently, SELECT COUNT(*) statements only count rows visible to the current transaction.

对于支持事务的储存引擎如InnoDB,储存一个准确的行数是存在问题的(注: 如不支持事务的MyISAM中的表会额外存在一个属性,储存并维护整个表的总行数,但如果使用WHERE进行查询函数,这个属性无法提供帮助)。因为在多事务并发情况下,每一个事务操作都有可能影响行数。

InnoDB并不会为表储存行数,因为事务并发执行的过程中,不同事务会发现不同的行数(注:所以上文中说支持事务的储存引擎无法储存准确的行数)。因此,count(*)只会计算当前事务中的行数。

Prior to MySQL 5.7.18, InnoDB processes SELECT COUNT(*) statements by scanning the clustered index. As of MySQL 5.7.18, InnoDB processes SELECT COUNT(*) statements by traversing the smallest available secondary index unless an index or optimizer hint directs the optimizer to use a different index. If a secondary index is not present, the clustered index is scanned.

在MySQL5.7.18之前,InnoDB通过查找聚集索引来处理SELECT count(*)语句。此后,InnoDB通过遍历最小可用二级索引来处理,除非一个索引或者一个hint导致优化器使用不同的索引。如果没有二级索引,将会使用聚集索引。

Processing SELECT COUNT(*) statements takes some time if index records are not entirely in the buffer pool. For a faster count, create a counter table and let your application update it according to the inserts and deletes it does. However, this method may not scale well in situations where thousands of concurrent transactions are initiating updates to the same counter table. If an approximate row count is sufficient, use SHOW TABLE STATUS.

当索引记录不在缓存池中完整存在时,执行SELECT count(*)将花费一些时间。如果想获得更快的速度,在创建一个计数表,当你的程序在执行插入或删除操作时更新相应的计数表。然而,这种方法在高并发场景,许多事务同事更新计数表时,结果不尽人意。如果有大量的相似行数,使用SHOW_TABLE_STATUS.

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.

For MyISAM tables, COUNT(*) is optimized to return very quickly if the SELECT retrieves from one table, no other columns are retrieved, and there is no WHERE clause.

This optimization only applies to MyISAM tables, because an exact row count is stored for this storage engine and can be accessed very quickly. COUNT(1) is only subject to the same optimization if the first column is defined as NOT NULL.

InnoDB以相同的方法处理count(*)和count(1),所以这两种表达式计算行数并没有性能上的差异。

MyISAM对count(*)进行了优化:如果不附带WHERE条件,单表查询情况下能非常快的得到数量。

上述的优化只对MyISAM的表有效,这是因为MyISAM储存引擎会记录准确行数,通过访问该数据可以快速得到行数。MyISAM中,只有在第一列被定义成 NOT NULL 的情况下,count(1)才能获得相同的优化。(注:所以在MyISAM中,count(*)和count(1)的效果可能不同,有无WHERE条件也会影响count()的效率)

count(*)和count(1)相关推荐

  1. count(1)、count(*) 与 count (列名) 的执行区别

    (给视学算法加星标,提升数据技能) 转自:BigoSprite https://blog.csdn.net/iFuMI/article/details/77920767 执行效果:  1.count( ...

  2. select count(*)加其他字段_count(1)、count(*) 与 count(列名) 的执行区别

    (给ImportNew加星标,提高Java技能) 作者:BigoSprite blog.csdn.net/iFuMI/article/details/77920767 执行效果: 1.  count( ...

  3. 关于数据库优化1——关于count(1),count(*),和count(列名)的区别,和关于表中字段顺序的问题...

    1.关于count(1),count(*),和count(列名)的区别 相信大家总是在工作中,或者是学习中对于count()的到底怎么用更快.一直有很大的疑问,有的人说count(*)更快,也有的人说 ...

  4. SQL Server中count(*), count(col), count(1)的对比

    SQL Server中count(*), count(col), count(1)的对比 原文:SQL Server中count(*), count(col), count(1)的对比 让我们先看一下 ...

  5. mysql 求count和_MySQL的统计总数count(*)与count(id)或count(字段)的之间的各自效率性能对比...

    执行效果: 1.  count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和coun ...

  6. Mysql之count(*),count(1),count(field)区别、性能差异

    目录 前言 COUNT(*)与 COUNT(1) MyISAM引擎中的COUNT(*)与 COUNT(1) Innodb引擎中的COUNT(*)与 COUNT(1) 实验 原理 结论 Count(1) ...

  7. mysql下count(*)和count(1)的区别

    2019独角兽企业重金招聘Python工程师标准>>> 今天看公司项目发现了一个奇怪sql写法 select count(8) from .... 这也许是开发人员不小心或者是习惯把 ...

  8. 执行COUNT(1)、COUNT(*) 与 COUNT(列名) 到底有什么区别?

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 来源:blo ...

  9. MySQL COUNT函数优化及count(1)/count(*)/count(列名)的区别

    count函数优化 使用近似值: 在某些应用场景中,不需要完全精确的值,可以参考使用近似值来代替,比如可以使用explain来获取近似的值.其实在很多OLAP的应用中,需要计算某一个列值的基数,有一个 ...

  10. 数据库面试题【十九、count(字段) count(主键 id) count(1)count(*)的区别】

    count(可空字段) 扫描全表,读到server层,判断字段可空,拿出该字段所有值,判断每一个值是否为空,不为空则累加 count(非空字段)与count(主键 id) 扫描全表,读到server层 ...

最新文章

  1. PostgreSQL在何处处理 sql查询之六十六
  2. 用AJAX实现无刷新的分页
  3. 其实我就是个技术迷-自身定位及展望
  4. [react] 在react中怎样改变组件状态,以及状态改变的过程是什么?
  5. Linux服务器操作系统 . 文件目录及文件管理
  6. 一文看懂网卡驱动原理及移植方法
  7. 队列同步器(AbstractQueuedSynchronizer)源码简析
  8. Java开发设计——七大原则
  9. Python GUI项目:文件夹管理系统
  10. 信捷触摸屏UI模板XINJIE UI信捷触摸屏界面模板
  11. 【自然语言处理】ChatGPT 相关核心算法
  12. vi/vim 解决按了ctrl+s之后无反应
  13. jni in linux
  14. MacOS 磁盘管理工具 diskutil 介绍
  15. 苏州市RFID客运车辆资产管理系统:RFID防盗资产管理-新导智能
  16. 哈工大-计算机系统-2022 | 大作业
  17. HNC-全局联想脉络
  18. 中国石墨轴承行业市场供需与战略研究报告
  19. Python爬虫练习(一):酷狗飙升榜前200_排行(使用select,find(),find_all()方法)
  20. 大容量充电宝哪种好?充电宝小巧容量大推荐

热门文章

  1. 【娱乐】王者荣耀·[优选秘宝]抽奖模拟程序
  2. 2022化工自动化控制仪表题库及在线模拟考试
  3. C++字符串数组 | 字符串数组输出
  4. 安卓手机卡顿怎么解决_iPhone手机变卡变慢怎么办?苹果手机卡顿解决小技巧
  5. PHP连接MYSQL数据库的3种常用方法
  6. 新版Chrome如何更换搜索引擎
  7. ABP框架初试(1)
  8. Cannot read field “parent“ because “comp“ is null
  9. TheBrain 9基础教程:界面功能篇(3)Thought的创建和设置
  10. 安卓和后端服务器数据交互