SELECT COUNT(*) FROM table_name是个再常见不过的统计需求了。

本文带你了解下Mysql的COUNT函数。

一、COUNT函数

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

翻译一下:

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

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

二、COUNT(列名)、COUNT(常量)和COUNT(*)

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

2.1 COUNT(*)和COUNT(常量)

在列名、常量和 *这三个条件中,常量是一个固定值,肯定不为NULL。*可以理解为查询整行,所以肯定也不为NULL,那么就只有列名的查询结果可能是NULL。

所以, 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的优化是完全一样的,根本不存在谁比谁快!

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会在扫表的时候选择最小的索引来降低成本。

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

三、总结

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

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

3.1 小建议

既然 count(*) 在查询上依赖于所有的数据集,所以我们在设计上也需要尽量的规避全量 count。

通常情况我们针对可预见的 count 查询会做适当的缓存,可以是 Redis,也可以是独立的 MySQL count 表。

3.2 技术交流

  1. 风尘博客
  2. 风尘博客-掘金
  3. 风尘博客-博客园
  4. Github

count(1)比count(*)效率高?的更多相关文章

  1. 你是一直认为 count(1) 比 count(*) 效率高么?

    MySQL count(1) 真的比 count(*) 快么? 反正同事们都是这么说的,我也姑且觉得对吧,那么没有自己研究一下究竟?如果我告诉你他们一样,你信么? 有 Where 条件的 count, ...

  2. 你还在认为 count(1) 比 count(*) 效率高?

    你还在认为 count(1) 比 count(*) 效率高? 3 很多人认为count(1)执行的效率会比count()高,原因是count()会存在全表扫描,而count(1)可以针对一个字段进行查 ...

  3. Select count(*)、Count(1)、Count(0)的区别和执行效率比较

    记得很早以前就有人跟我说过,在使用count的时候要用count(1)而不要用count(*),因为使用count(*)的时候会对所有的列进行扫描,相比而言count(1)不用扫描所有列,所以coun ...

  4. MySQL的统计总数count(*)与count(id)或count(字段)的之间的各自效率性能对比

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

  5. mysql 5.7中 count(0) count(*) count(主键) count(非空字段)效率比较

    mysql count(0) count(*) count(主键) count(非空字段) 效率比较 写代码的时候经理在背后说了一句count(0)的效率高于count(*) ,索性全部测试了一下 结 ...

  6. select count(*)和select count(1)哪个性能高

    select count(*).count(数字).count(字段名)在相同的条件下是没有性能差别的,一般我们在统计行数的时候都会把NULL值统计在内的,所以这样的话,最好就是使用COUNT(*) ...

  7. select count(*)和select count(1)的区别 (转)

    A 一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的 假如表沒有主键(Primary key), 那么count(1)比count(*)快, 如果有主键 ...

  8. count(*),count(1)和count(主键) 区别

    看如下数据: SQL> select count(*) from ysgl_compile_reqsub; COUNT(*) ---------- 已用时间: : : 07.51 SQL) fr ...

  9. sql中奇怪的sum(1),sum(2),count(1),count(6),count(*):统计总数

    sql的统计函数 sql统计函数有 count 统计条数,配合group用 sum 累加指定字段数值 但注意sum(1)就特殊 sum(1)等同于count(*) sum(1)统计个数,功能和coun ...

随机推荐

  1. 【java面试】算法篇之堆排序

    一.堆的概念 堆是一棵顺序存储的完全二叉树.完全二叉树中所有非终端节点的值均不大于(或不小于)其左.右孩子节点的值. 其中每个节点的值小于等于其左.右孩子的值,这样的堆称为小根堆: 其中每个节点的值大 ...

  2. 51Nod 1238 最小公倍数之和V3

    题目传送门 分析: 现在我们需要求: \(~~~~\sum_{i=1}^{n}\sum_{j=1}^{n}lcm(i,j)\) \(=\sum_{i=1}^{n}\sum_{j=1}^{n}\frac ...

  3. Day10-Python3基础-协程、异步IO、redis缓存、rabbitMQ队列

    内容目录: Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko S ...

  4. SpringBoot2.x整合JDBC及初始化data.sql和schema.sql脚本

    今天在使用SpringBoot2.x版本整合JDBC时遇到了一些问题:由于我之前一直用SpringBoot1.5的版本,所以直接在yml里按照1.5的版本配置了属性,没想到2.x直接不能用了.首先是数 ...

  5. logback 发送邮件和自定义发送邮件;java类发送邮件

    使用logback发送邮件 需求: 1.报错发邮件,定位错误位置以尽快解决:(报错发送邮件) 2.某一项重要操作完成之后发送邮件:(自定义发送邮件) 没有接触过logback,怎么办? 没办法,硬着头 ...

  6. Centos7 下搭建STF平台

    STF,全名Smartphone Test Farm---智能手机测试平台,可以提供远程真机调试的功能,目前仅支持Android设备. 环境准备 1.Node.js 8 安装Node.js $ cur ...

  7. jQuery使用ajax向node后台发送对象、数组参数

    引言 最近在使用jq,做一些小demo,但是突然发现jq使用ajax像后台(node)传递一个对象参数,但是后台却接收不了. 原因 后面了解到.jq会将一个对象解析成obj[key]: value这样 ...

  8. 安装MySQL出现[Errno 256] No more mirrors to try

    今天安装数据库时出现错误提示,如下图: 解决办法如下: yum clean all #清除仓库缓存 yum makecache #将服务器包信息缓存到本地 然后再执行数据库安装指令 yum insta ...

  9. VS2013下搭建SDL开发环境

    什么是SDL? SDL是 "Simple DirectMedia Layer"的缩写,它是一个开源的项目. 为多媒体编程而设计 SDL是一个跨平台的多媒体库,它通过OpenGL和2 ...

  10. C语言关于getchar()的小笔记

    #include <windows.h> #include <mmsystem.h> #include <string.h> void main() { int a ...