MySQL45讲之count操作
2021/9/16 2:05:02
本文主要是介绍MySQL45讲之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 查询数据的操作不是原子的,数据就不是一致的。
2、数据库统计表记录
数据库新建一个统计表记录行数。那不是和前一个方法一样么,并发请求下得到的结果可能不一致。
可以的,行数据和统计数据同时存在数据库中,并且数据库支持事务,所以可以将多个操作封装成原子的,保证数据一致。
多种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这么慢,我该怎么办
这篇关于MySQL45讲之count操作的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-20部署MySQL集群入门:新手必读指南
- 2024-11-20部署MySQL集群教程:初学者指南
- 2024-11-20部署MySQL集群项目实战:新手教程
- 2024-11-20部署MySQL集群资料:新手入门教程
- 2024-11-20MySQL集群部署教程:入门级详解
- 2024-11-20MySQL集群教程:入门与实践指南
- 2024-11-20部署MySQL集群教程:新手入门指南
- 2024-11-20MySQL读写分离教程:轻松入门
- 2024-11-20部署MySQL集群入门:一步一步搭建你的数据库集群
- 2024-11-19部署MySQL集群学习:入门教程