不同的 count 用法效率:在 select count(?) from t 这样的查询语句里面,

count(*)、count(主键 id)、count(字段) 和 count(1) 等不同用法的性能,有哪些差别。今天谈到了 count(*) 的性能问题,我就借此机会和你详细说明一下这几种用法的性能差别。需要注意的是,

下面的讨论还是基于 InnoDB 引擎的。

这里,首先你要弄清楚 count() 的语义。count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。

所以,count(*)、count(主键 id) 和 count(1) 都表示返回满足条件的结果集的总行数;而 count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数。至于分析性能差别的时候,你可以记住这么几个原则:

server 层要什么就给什么;

InnoDB 只给必要的值;现在的优化器只优化了 count(*) 的语义为“取行数”,其他“显而易见”的优化并没有做。这是什么意思呢?接下来,我们就一个个地来看看。

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

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

单看这两个用法的差别的话,你能对比出来,count(1) 执行得要比 count(主键 id) 快。因为从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。

对于 count(字段) 来说:

1. 如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;

2. 如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。也就是前面的第一条原则,server 层要什么字段,InnoDB 就返回什么字段。

但是 count(*) 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*) 肯定不是 null,按行累加。看到这里,你一定会说,优化器就不能自己判断一下吗,主键 id 肯定非空啊,为什么不能按照 count(*) 来处理,多么简单的优化啊。当然,MySQL 专门针对这个语句进行优化,也不是不可以。但是这种需要专门优化的情况太多了,而且 MySQL 已经优化过 count(*) 了,你直接使用这种用法就可以了。

所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)。

不同的 count 用法的更多相关文章

  1. mysql SELECT FOUND_ROWS()与COUNT(*)用法区别

    在mysql中 FOUND_ROWS()与COUNT(*)都可以统计记录,如果都一样为什么会有两个这样的函数呢,下面我来介绍SELECT FOUND_ROWS()与COUNT(*)用法区别   SEL ...

  2. SQL - SELECT COUNT用法

     SQL Server数据库  COUNT() 函数返回匹配指定条件的行数.   语法   SQL COUNT(column_name) 语法   COUNT(column_name) 函数返回指定列 ...

  3. Selenium2Library:Get Matching Xpath Count用法

    Name:Get Matching Xpath CountSource:Selenium2Library <test library>Arguments:[ xpath ]Returns ...

  4. MySQL:count()用法

    语法 COUNT() 函数返回匹配指定条件的行数. COUNT(column_name) 语法 COUNT(column_name) 函数返回指定列的值的数目(NULL 不计入): SELECT CO ...

  5. 数据库count用法

    count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL  count(1)包括了所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL  count(列名)只包 ...

  6. count()用法

  7. mysql count max min 语句用法

    count 用法 求总条数 $sql="select count(*) as total from e_user"; $query = mysql_query($sql, $lin ...

  8. memcpy函数用法

    memcpy函数用法 .分类: VC++ VC++ mfc matlab 2011-12-01 19:17 14538人阅读 评论(0) 收藏 举报 null 原型:extern void *memc ...

  9. memcpy的用法总结

    1.memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域):拷贝多少个?有一个size变量控制拷贝的字节数:函数原型:void *memcpy(voi ...

随机推荐

  1. Java基础00-常用API24

    1. Math Math 1.1 Math类概述 1.2 Math类的常用方法 返回绝对值:是正数是时候直接返回参数本身,是负值的时候返回的是参数的相反数.参数是10时返回的是10,参数是-10的时候 ...

  2. Java基础00-集合基础15

    1. 集合基础 1.1 集合概述 1.2 ArrayList构造方法和添加方法 代码示例: 想通过指定索引添加到最后一个位置的话就填写,现有索引的+1,比如3个索引就是4.如果在指定索引的位置添加没有 ...

  3. python3执行.sql文件

    这个脚本主要是遍历执行文件夹下的sql文件,但是没有辨别文件的格式,所以文件夹下只能够放.sql文件,否则会报错哈. 我的sql文件夹与执行的文件平级,所以dir_path就是sql,大家依照自己的路 ...

  4. English Study!

    As you konw, education is a top priority for us !  When the times abandon you, they don't even call ...

  5. Visual Studio2019下载最新离线安装包

    首先可以参考微软官方的离线安装说明-->点击这里打开 =================================================================== 1. ...

  6. salesforce Integration 概览(一) 杂篇

    本篇参考:https://resources.docs.salesforce.com/sfdc/pdf/integration_patterns_and_practices.pdf 我们在做sales ...

  7. nfs(2049)未授权访问

    apt install nfs-common 安装nfs客户端 showmount -e 192.168.244.128 查看nfs服务器上的共享目录 /666/share               ...

  8. Apache ActiveMQ(CVE-2016-3088)

    影响版本 Apache ActiveMQ 5.0.0-5.13.x 路径地址 http://192.168.49.2:8161/admin/test/systemProperties.jsp 该漏洞允 ...

  9. helm离线安装helm-push插件

    helm-push版本:helm-push_0.9.0_linux_amd64 helm-push安装包 百度云: 链接:  helm-push_0.9.0_linux_amd64  提取码: 26b ...

  10. Python小白的数学建模课-12.非线性规划

    非线性规划是指目标函数或约束条件中包含非线性函数的规划问题,实际就是非线性最优化问题. 从线性规划到非线性规划,不仅是数学方法的差异,更是解决问题的思想方法的转变. 非线性规划问题没有统一的通用方法, ...