mysqlcount和countid(mysql的count能count几个)

技术MySQL中的count(*)和count(1)哪个更快这篇文章主要讲解了“MySQL中的count(*)和count(1)哪个更快”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来

本文主要讲解“MySQL中的count(*)和count(1)哪个更快”。本文的解释简单明了,易学易懂。现在请跟随边肖的思路,一起学习和学习“MySQL中的count(*)和count(1)哪个更快”!

MySQL中的count(*)和count(1)哪个更快

免责声明:以下讨论基于InnoDB存储引擎,MyISAM因其特殊情况将在本文最后单独谈。

第一个结论:这两个性能差别不大。

00-1010我准备了一张包含100瓦数据的表格。表格结构如下:

CREATETABLE`user `(

` id ` int(11)UNsignedNonNullAutO _ INDEX,

` username ` varchar(255)DEFAULT NULL,

` address ` varchar(255)DEFAULT NULL,

` password ` varchar(255)DEFAULT NULL,

PRIMARYKEY(`id `)

)ENGINE=innoddefaultcharset=utf 8 MB 4;可以看到有一个主键索引。

让我们用两种方法来统计表中的记录,如下所示:

MySQL中的count(*)和count(1)哪个更快

可以看到两个SQL的执行效率几乎是一样的,都是0.14s

看看另外两个统计数据:

MySQL中的count(*)和count(1)哪个更快

Id是主键,用户名和地址是普通字段。

可以看出,按id计数也有失去的优势。宋哥,因为这里的测试数据模板比较小,效果不明显。如果朋友们能增加测试数据,差别会更明显。

那么,造成这种差异的原因是什么呢?接下来我们简单分析一下。

00-1010让我们用解释来看看不同的SQL执行计划:

MySQL中的count(*)和count(1)哪个更快

可以看到,前三种统计方式的实施方案是一样的,后两种也是一样的。

让我在这里与您比较一下解释中的不同项目:

Type:前三个的type值为index,表示全索引扫描,即只需遍历整个索引(http://www . Sina.com/);最后两个的类型值是all,这意味着注意是索引不是整个表,也就是索引不会被使用。

Key:这意味着MySQL决定使用哪个索引来优化对表的访问,PRIMARY表示使用主键索引,NULL表示不使用索引。

Key_len:表示MySQL使用的密钥长度。因为我们的主键类型是INT,不是空的,所以值是4。

额外:这里的Using索引意味着优化器只能通过访问索引(不返回表)来获取所需的数据。

全表扫描

光有以上分析是不够的。我们从原理的角度来分析一下。

1.实践

通过 explain 我们其实也能大概看出来前三种统计方式的执行效率是要高一些的(因为用到了索引),而后面两种的统计效率相对来说要低一些的(没用索引,需要全表扫描)。

在开始原理分析之前,我想给大家看一下B树,这对我们理解下面的内容非常重要。

众所周知,InnoDB中索引的存储节点

构都是 B+ 树(至于什么是 B+ 树,和 B 树有什么区别,这个本文就不讨论了,这两个单独都能整出来一篇文章),主键索引和普通索引的存储又有所不同,如下图表示主键索引:

MySQL中的count(*)和count(1)哪个更快

可以看到,在主键索引中,叶子结点保存了每一行的数据。

而在普通索引中,叶子结点保存的是主键值,当我们使用普通索引去搜索数据的时候,先在叶子结点中找到主键,再拿着主键去主键索引中查找数据,相当于做了两次查找,这也就是我们平常所说的回表操作。

3.2 原理分析

不知道小伙伴们有没有注意过,我们学习 MySQL 的时候,count 函数是归在聚合函数那一类的,就是 avg、sum 等,count 函数和这些归在一起,说明它也是一个聚合函数。

既然是聚合函数,那么就需要对返回的结果集进行一行行的判断,这里就涉及到一个问题,返回的结果是啥?我们分别来看:

对于 select count(1) from user; 这个查询来说,InnoDB 引擎会去找到一个最小的索引树去遍历(不一定是主键索引),但是不会读取数据,而是读到一个叶子节点,就返回 1,最后将结果累加。

对于 select count(id) from user;  这个查询来说,InnoDB 引擎会遍历整个主键索引,然后读取 id 并返回,不过因为 id 是主键,就在 B+ 树的叶子节点上,所以这个过程不会涉及到随机 IO(并不需要回表等操作去数据页拿数据),性能也是 OK 的。

对于 select count(username) from user;  这个查询来说,InnoDB 引擎会遍历整张表做全表扫描,读取每一行的 username 字段并返回,如果 username 在定义时候设置了 not null,那么直接统计 username 的个数;如果 username 在定义的时候没有设置 not null,那么就先判断一下 username 是否为空,然后再统计。

最后再来说说 select count(*) from user; ,这个 SQL 的特殊之处在于它被 MySQL 优化过,当 MySQL 看到 count(*) 就知道你是想统计总记录数,就会去找到一个最小的索引树去遍历,然后统计记录数。

因为主键索引(聚集索引)的叶子节点是数据,而普通索引的叶子节点则是主键值,所以普通索引的索引树要小一些。然而在上文的案例中,我们只有主键索引,所以最终使用的就是主键索引。

现在,如果我修改上面的表,为 username 字段也添加索引,然后我们再来看 explain select count(*) from user; 的执行计划:

MySQL中的count(*)和count(1)哪个更快

可以看到,此时使用的索引就是 username 索引了,和我们前面的分析结果是一致的。

从上面的描述中我们就可以看出,第一个查询性能最高,第二个次之(因为需要读取 id 并返回),第三个最差(因为需要全表扫描),第四个的查询性能则接近第一个。

4. MyISAM 呢?

可能有小伙伴知道,MyISAM 引擎中的 select count(*) from user; 操作执行起来是非常快的,那是因为 MyISAM 把表中的行数直接存在磁盘中了,需要的时候直接读取出来就行了,所以非常快。

MyISAM 引擎之所以这样做,主要是因为它是不支持事务的,所以它的统计实际上就非常容易,添加一行记录一行就行了。

而我们常用的 InnoDB 却不能这样做!为啥?因为 InnoDB 支持事务!为了支持事务,InnoDB 引入了 MVCC 多版本并发控制,所以在数据读取的时候可能会有脏读、幻读以及不可重复读等问题,

感谢各位的阅读,以上就是“MySQL中的count(*)和count(1)哪个更快”的内容了,经过本文的学习后,相信大家对MySQL中的count(*)和count(1)哪个更快这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/154050.html

(0)

相关推荐

  • 两个二声在一起怎么读,两个二声叠字连读比如妤妤怎么读

    技术两个二声在一起怎么读,两个二声叠字连读比如妤妤怎么读谢邀两个二声在一起怎么读。联绵字是从语义上来分析的,一个双字词不能被拆分为两个单字词,那么这个词的两个字就是联绵字。比如蛤蟆,不能被拆分为蛤和蟆,蜈蚣,不能拆为蜈和

    生活 2021年10月22日
  • SpringBoot+Mybatis plus如何实现多数据源整合的实践

    技术SpringBoot+Mybatis plus如何实现多数据源整合的实践SpringBoot+Mybatis plus如何实现多数据源整合的实践,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方

    攻略 2021年10月22日
  • 【P6】Verilog搭建流水线MIPS-CPU,全指令55条)

    技术【P6】Verilog搭建流水线MIPS-CPU,全指令55条) 【P6】Verilog搭建流水线MIPS-CPU(全指令55条)我开P6是过P5了吗笑死,P5又挂了,还是经典的blezalc指令,

    礼包 2021年12月16日
  • 投入的近义词,“尽心尽力”类似的词语有哪些

    技术投入的近义词,“尽心尽力”类似的词语有哪些竭尽全力[jiéjìnquánlì]?:形容用尽全部力量投入的近义词。
    尽心尽力[jìnxīnjìnlì]:做事非常的卖力,或为非常的卖命,以用尽了自己所有的能力。
    尽心尽责

    生活 2021年10月30日
  • 衣补旁,衣补旁和四补旁有什么区别

    技术衣补旁,衣补旁和四补旁有什么区别一衣补旁、笔画数不同 1、四补旁:礻为示字旁,笔画数为四笔。 2、衣补旁:衤为衣字旁,笔画数为五笔。
    二、来源不同
    1、四补旁:同“示”。用作偏旁。俗称“示字旁”。
    2、衣补旁:

    生活 2021年10月24日
  • Mysql RELICATION对存过的处理是怎样的

    技术Mysql RELICATION对存过的处理是怎样的本篇文章给大家分享的是有关Mysql RELICATION对存过的处理是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说

    攻略 2021年11月20日