• 首页
  • 国产小呦泬泬99精品
  • 最近2019中文字幕在线高清
  • 免费看少妇作爱视频
  • 曰批全过程免费视频在线观看网站
  • 国色天香在线观看全集免费播放
  • 婆岳同床双飞呻吟
  • 婆岳同床双飞呻吟你的位置:三级小说 > 婆岳同床双飞呻吟 > 纳尼?MySQL 中 count(*) 比 count(1) 快?

    纳尼?MySQL 中 count(*) 比 count(1) 快?

    发布日期:2022-06-18 17:11    点击次数:109

    纳尼?MySQL 中 count(*) 比 count(1) 快?

    今天有人跟我讲 MySQL 中 count(1) 比 count(*) 快,这能忍?必须得和他掰扯掰扯。

    声明:以下操办基于 InnoDB 存储引擎,MyISAM 因为情况稀奇我在文末会单独说一下。

    先说论断:这两个性能离别不大。

    1.执行

    我准备了一张有 100W 条数据的表,表结构如下:

    CREATE TABLE `user` (   `id` int(11) unsigned NOT NULL AUTO_INCREMENT,   `username` varchar(255) DEFAULT NULL,   `address` varchar(255) DEFAULT NULL,   `password` varchar(255) DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

    不错看到,有一个主键索引。

    咱们来用两种样貌统计一下表中的记载数,如下:

    不错看到,两条 SQL 的践诺效力其实差未几,都是 0.14s。

    再来看另外两个统计:

    id 是主键,username 以及 address 则是通俗字段。

    不错看出,用 id 来统计,也有一丢丢上风。松哥这里因为测试数据样板相比小,是以恶果不剖析,小伙伴们不错加大测试数据量,那么这种各异会愈加剖析。

    那么到底是什么原因形成的这种各异,接下来咱们就来通俗分析一下。

    2. explain 分析

    咱们先用 explain 来看下这几个 SQL 不同的践诺权术:

    不错看到,前三个统计样貌的践诺权术是通常的,后头两个是通常的。

    我这里和公共相比下 explain 中的不同项:

    type:前三个的 type 值为 index,暗意全索引扫描,等于把通盘索引过一遍就行(细巧是索引不是通盘表);后两个的 type 值为 all,暗意全表扫描,即不会使用索引。 key:这个暗意 MySQL 决定接纳哪个索引来优化对该表的探员,PRIMARY 暗意哄骗主键索引,NULL 暗意无谓索引。 key_len:这个暗意 MySQL 使用的键长度,因为咱们的主键类型是 INT 且非空,是以值为 4。 Extra:这个中的 Using index 暗意优化器只需要通过探员索引就不错取得到需要的数据(不需要回表)。

    通过 explain 咱们其实也能粗略看出来前三种统计样貌的践诺效力是要高一些的(因为用到了索引),尔后头两种的统计效力相对来说要低一些的(没用索引,需要全表扫描)。

    仅有上头的分析还不够,咱们再来从旨趣角度来分析一下。

    3. 旨趣分析 3.1 主键索引与通俗索引

    在驱动旨趣分析昔时,我想先指导公共看一下 B+ 树,这关于咱们意会接下来的内容有弥留作用。

    公共都澄莹,InnoDB 中索引的存储结构都是 B+ 树(至于什么是 B+ 树,和 B 树有什么区别,这个本文就不操办了, 97视频这两个单独都能整出来一篇著述),主键索引和通俗索引的存储又有所不同,如下图暗意主键索引:

    不错看到,在主键索引中,叶子结点保存了每一瞥的数据。

    而在通俗索引中,叶子结点保存的是主键值,当咱们使用通俗索引去搜索数据的技能,先在叶子结点中找到主键,再拿着主键去主键索引中查找数据,绝顶于做了两次查找,这也等于咱们无为所说的回表操作。

    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; 的践诺权术:

    不错看到,此时使用的索引等于 username 索引了,和咱们前边的分析收尾是一致的。

    从上头的姿色中咱们就不错看出,第一个查询性能最高,第二个次之(因为需要读取 id 并复返),第三个最差(因为需要全表扫描),第四个的查询性能则接近第一个。

    4. MyISAM 呢?

    可能有小伙伴澄莹,MyISAM 引擎中的 select count(*) from user; 操作践诺起来长短常快的,那是因为 MyISAM 把表中的行数班师存在磁盘中了,需要的技能班师读取出来就行了,是以相等快。

    MyISAM 引擎之是以这么做,主如果因为它是不撑持事务的,是以它的统计骨子上就相等容易,添加一瞥记载一瞥就行了。

    而咱们常用的 InnoDB 却不可这么做!为啥?因为 InnoDB 撑持事务!为了撑持事务,InnoDB 引入了 MVCC 多版块并发收尾,是以在数据读取的技能可能会有脏读、幻读以及不可重叠读等问题,具体不错参考 https://www.bilibili.com/video/BV14L4y1B7mB 视频。

    是以,InnoDB 需要将每一瞥数据拿出来,判断该行数据对刻下会话是否可见,如果可见,就统计该行数据,不然不予统计。

    虽然,MySQL 中的 MVCC 骨子上是一个相等巨大的话题,松哥以后有空了再和公共详备先容 MVCC。

     

    好啦,面前小伙伴们懂了吧?有问题迎接留言操办。

     



    Powered by 三级小说 @2013-2022 RSS地图 HTML地图