返回顶部
首页 > 资讯 > 数据库 >MySQL45讲之count操作 - flowers
  • 228
分享到

MySQL45讲之count操作 - flowers

MySQL45讲之count操作-flowers 2021-05-25 03:05:51 228人浏览 无得
摘要

本文介绍 MyISAM 和 InnoDB 如何执行 count 操作,如果是一个需要使用 count 进行大量计数的场景,应该如何设计实现,以及不同 count 操作的效率。 前言 本文介绍

MySQL45讲之count操作 - flowers

本文介绍 MyISAM 和 InnoDB 如何执行 count 操作,如果是一个需要使用 count 进行大量计数的场景,应该如何设计实现,以及不同 count 操作的效率。

前言

本文介绍 MyISAM 和 InnoDB 如何执行 count 操作,如果是一个需要使用 count 进行大量计数的场景,应该如何设计实现,以及不同 count 操作的效率。

MyISAM和InnoDB的count

MyISAM

MyISAM 存储引擎的每个表记录了总行数,在没有 where 条件时,直接获取该记录值返回。

InnoDB

InnoDB 获取 count 值,只能通过扫描索引树来计数。

为什么 InnoDB 只能临时扫描来计数,而不能像 MyISAM 一样存储一个总行数值?
对于同一时刻的多个查询请求,因为并发版本控制的原因,InnoDB 表应该返回多少行是不确定的,需要扫描索引,判断每行记录的可见性。

此外,InnoDB 也做了一些优化。主键索引树存储了行记录,而普通索引树只存储主键值,所以普通索引树比主键索引树小很多。因此,Mysql 会优先选择最小的索引树来遍历。在保证逻辑正确的情况下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

count值如何记录

1、缓存记录

比如在 Redis 中用 string 类型记录一个计数,当新增或者删除记录时,相应修改 Redis 的值。

这样是不行的,没法保证数据的一致性

首先,如果业务系统插入或删除一行数据后,系统宕机,Redis 没有写入,重启系统后 Redis 会与数据库不一致。不过,这个问题可以通过系统重启时从数据库查询一次解决。

而且,如果需要同时从 Redis 和数据库中查询数据,两者无法保证数据一致,比如从 Redis 中取出表总行数和从数据库中取出前 100 行数据。因为并发请求,只要从 Redis 和 mysql 查询数据的操作不是原子的,数据就不是一致的。

数据库统计表记录

数据库新建一个统计表记录行数。那不是和前一个方法一样么,并发请求下得到的结果可能不一致。

可以的,行数据和统计数据同时存在数据库中,并且数据库支持事务,所以可以将多个操作封装成原子的,保证数据一致。

多种count操作的效率

count(主键id)

存储引擎遍历表拿到行记录返回,server 层解析出 id 值,判断是否为 null,统计行数。

count(1)

存储引擎遍历表不取值,server 层对于每一行放进去一个 1,判断是否为 null,统计行数。

因为 server 层需要解析引擎返回的结果拿到 id,所以 count(1) 比 count(主键id) 高效。

count(字段)

存储引擎遍历表取出字段返回,server 层解析,判断字段是否为 null,统计行数。

count(*)

Mysql 进行了优化,存储引擎遍历表不取值,server 层判断是否为 null,逐行累加。

效率从高到低:count(*) ≈ count(1) > count(主键id) > count(字段)

提问

在刚刚讨论的方案中,我们用了事务来确保计数准确。由于事务可以保证中间结果不被别的事务读到,因此修改计数值和插入新记录的顺序是不影响逻辑结果的。

但是,从并发系统性能的角度考虑,你觉得在这个事务序列里,应该先插入操作记录,还是应该先更新计数表呢?

先执行插入操作,再执行更新操作。从并发系统性能的角度考虑,应该尽可能减少等待,而更新操作需要加行锁,行锁在事务提交之后才会释放。所以最后执行更新操作,减少锁等待,提高并发度。

参考

  • [1] count这么慢,我该怎么办
您可能感兴趣的文档:

--结束END--

本文标题: MySQL45讲之count操作 - flowers

本文链接: https://lsjlt.com/news/8752.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作