count(1)比count(*)效率高?

SELECT COUNT(*) FROM table_name是个再常见不过的统计需求了。
本文带你了解下MysqlCOUNT函数。php

1、COUNT函数

关于COUNT函数,在MySQL官网中有详细介绍html

风尘博客

翻译一下:mysql

  1. COUNT(expr) ,返回SELECT语句检索的行中expr的值不为NULL的数量,结果是一个BIGINT值。
  2. 若是查询结果没有命中任何记录,则返回0
  3. COUNT(*) 的统计结果中,会包含值为NULL的行数。

《阿里巴巴Java开发手册》也有以下要求:git

风尘博客

2、COUNT(列名)COUNT(常量)COUNT(*)

前面咱们提到过COUNT(expr)用于作行数统计,那么COUNT(列名)COUNT(常量)COUNT(*)这三种语法中,expr分别是列名、 常量 和 *github

2.1 COUNT(*)COUNT(常量)

在列名、常量和*这三个条件中,常量是一个固定值,确定不为NULL*能够理解为查询整行,因此确定也不为NULL,那么就只有列名的查询结果多是NULLsql

因此, COUNT(常量)COUNT(*)表示的是直接查询符合条件的数据库表的行数。而COUNT(列名)表示的是查询符合条件的列的值不为NULL的行数。数据库

2.2 COUNT(*)COUNT(1)区别

COUNT(1)就是COUNT(常量),对于这两者到底有没有区别:缓存

  1. 有的说COUNT(*)执行时会转换成COUNT(1),因此COUNT(1)少了转换步骤,因此更快。
  2. 还有的说,由于MySQL针对COUNT(*)作了特殊优化,因此COUNT(*)更快。

到底哪一种说法是对的?看下MySQL官方文档:函数

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

经过文档,对于COUNT(1)COUNT(*)MySQL的优化是彻底同样的,根本不存在谁比谁快!post

2.3 COUNT(列名)

相较于前二者,COUNT(列名)的查询就比较简单粗暴了,就是进行全表扫描,而后判断指定字段的值是否是为NULL,不为NULL则累加。

相比COUNT(*)COUNT(列名)多了一个步骤就是判断所查询的字段是否为NULL,因此他的性能要比COUNT(*)慢。
here和group的条件查询。

2.4 SQL92

除了查询获得结果集有区别以外,COUNT(*)相比COUNT(常量)COUNT(列名)来说,COUNT(*)SQL92定义的标准统计行数的语法,由于他是标准语法,因此MySQL数据库对他进行过不少优化。

SQL92,是数据库的一个ANSI/ISO标准。它定义了一种语言(SQL)以及数据库的行为(事务、隔离级别等)。

2.5 COUNT(*)优化

由于COUNT(*)SQL92定义的标准统计行数的语法,因此MySQL对其进行了不少优化:

  1. MyISAM中会直接把表的总行数单独记录下来供COUNT(*)查询
  2. InnoDB会在扫表的时候选择最小的索引来下降成本。

这些优化的前提都是没有进行wheregroup的条件查询,更多请参考MySQL 全表 COUNT(*) 简述

3、总结

COUNT函数用于统计表行数,按照效率比较的话:

count(*)=count(常量)>count(列名)

3.1 小建议

既然 count(*) 在查询上依赖于全部的数据集,因此咱们在设计上也须要尽可能的规避全量 count

一般状况咱们针对可预见count 查询会作适当的缓存,能够是 Redis,也能够是独立的 MySQL count 表。

3.2 技术交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. Github
相关文章
相关标签/搜索