为什么 select count(*) from t,在 InnoDB 引擎中比 MyISAM 慢?
统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from t
SQL 语句来完成。随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什么它会变慢呢?
为什么会变慢?想要得到答案就需要知道 MySQL 是如何统计总数量的,先说一个前提吧,count(*)
的具体实现是由存储引擎实现的,也就是说不同的存储引擎实现的方式不一样。标题:为什么 select count( * ) from t
,在 InnoDB 引擎中比 MyISAM 慢?也是高频面试题。
InnoDB和MyISAM 是我们常用的 MySQL 存储引擎,所以主要对比一下 count(*)
在 InnoDB 和 MyISAM 中的实现:
- 在 MyISAM 存储引擎中,把表的总行数存储在磁盘上,当执行 select count(*) from t 时,直接返回总数据。
- 在 InnoDB 存储引擎中,跟 MyISAM 不一样,没有将总行数存储在磁盘上,当执行 select count(*) from t 时,会先把数据读出来,一行一行的累加,最后返回总数量。
知道了 InnoDB 和 MyISAM 引擎 count(*) 实现之后,为什么 select count(*) from t
,在 InnoDB 引擎中比 MyISAM 慢?应该有答案了吧,但是这个结论需要有一个前提,就是统计 SQL 不带过滤条件。如果 统计数量 SQL 语句为:select count(*) from t where x = 23
,那么在 MyISAM 中就不一定比 InnoDB 快了。
InnoDB 中 count(*) 语句是在执行的时候,全表扫描统计总数量,所以当数据越来越大时,语句就越来越耗时了,为什么 InnoDB 引擎不像 MyISAM 引擎一样,将总行数存储到磁盘上?这跟 InnoDB 的事务特性有关,由于多版本并发控制(MVCC)的原因,InnoDB 表“应该返回多少行”也是不确定的。
不妨用一个例子来说明一下,假设现在 t 表中有 10000 条数据,现在有三个用户同时访问的会话:
- 会话 A 先启动事务并查询一次表的总行数。
- 会话 B 启动事务,插入一行后记录后,查询表的总行数。
- 会话 C 先启动一个单独的语句,插入一行记录后,查询表的总行数。
假设从上到下是按照时间顺序执行的,同一行语句是在同一时刻执行的。可以看出在最后时刻,三个会话返回的总行数不一样。
出现不一样的结果跟 InnoDB 存储引擎有关系,在默认隔离级别可重复读的情况下,通过多版本并发控制(MVCC)来实现,每一行记录都需要判断自己是否对这个会话可见,因此在统计总数量时,InnoDB 只好把数据一行一行的读取出来判断,只有当前会话可见的才纳入统计中。所以同一时刻不同会话查询到的数量就不一样。
InnoDB 引擎在 count(*)
语句上也做了优化,我们知道,在 InnoDB 存储引擎中是以索引组织表的方式存储数据,主键索引树上叶子节点存放在所有的数据,而普通索引树的叶子节点是主键值,所以普通索引树会比主键索引树小很多,但是数量是一样的,也就是说遍历主键索引树和普通索引树得到的结果都是一样的。MySQL 就利用了这一特性,在 InnoDB 中执行 select count(*) from t
语句时,MySQL 优化器会找到最小的那棵索引树来遍历,这样可能就可以减少加载次数,在一定程度上提升了 count(*)的执行效率。
最后
目前互联网上很多大佬都有MySQL相关文章,如有雷同,请多多包涵了。原创不易,码字不易,还希望大家多多支持。若文中有所错误之处,还望提出,谢谢。
为什么 select count(*) from t,在 InnoDB 引擎中比 MyISAM 慢?的更多相关文章
- Innodb引擎中Count(*)
select count(*)是MySQL中用于统计记录行数最常用的方法,count方法可以返回表内精确的行数. 在某些索引下是好事,但是如果表中有主键,count(*)的速度就会很慢,特别在千万记录 ...
- 聊一聊 InnoDB 引擎中的索引类型
索引对数据库有多重要,我想大家都已经知道了吧,关于索引可能大家会对它多少有一些误解,首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书 ...
- 聊一聊 InnoDB 引擎中的这些索引策略
在上一篇中,我们简单的介绍了一下 InnoDB 引擎的索引类型,这一篇我们继续学习 InnoDB 的索引,聊一聊索引策略,更好的利用好索引,提升数据库的性能,主要聊一聊覆盖索引.最左前缀原则.索引下推 ...
- InnoDB 引擎中的索引类型
首先索引是一种数据结构,并且索引不是越多越好.合理的索引可以提高存储引擎对数据的查询效率. 形象一点来说呢,索引跟书本的目录一样,能否快速的查找到你需要的信息,取决于你设计的目录是否合理. MySQL ...
- MySQL存储引擎中的MyISAM和InnoDB区别详解
在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...
- MySQL存储引擎中的MyISAM和InnoDB区别
MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Method:有索引的顺序访问方法)所改良.虽然性能极佳,但却有一个缺点 ...
- 【Mysql】—— MySQL存储引擎中的MyISAM和InnoDB区别详解
在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...
- MySQL存储引擎中的MyISAM和InnoDB
在使用MySQL的过程中对MyISAM和InnoDB这两个概念存在了些疑问,到底两者引擎有何分别一直是存在我心中的疑问.为了解开这个谜题,搜寻了网络,找到了如下信息: MyISAM是MySQL的默认数 ...
- 【转】MySQL存储引擎中的MyISAM和InnoDB区别详解
转自:http://www.jb51.net/article/62457.htm MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Ac ...
随机推荐
- Python拾遗(2)
包括Python中的常用数据类型. int 在64位平台上,int类型是64位整数: 从堆上按需申请名为PyIntBlcok的缓存区域存储整数对象 使用固定数组缓存[-5, 257]之间的小数字,只需 ...
- (三)mybatis级联的实现
mybatis级联的实现 开篇 级联有三种对应关系: 1.一对一(association):如学号与学生 2.一对多(collection):如角色与用户 3.多对多(discri ...
- 谷歌Waymo估值700亿:自动驾驶迎来春天,但前路漫漫
在经过近一年的法庭之争后,Waymo与Uber的自动驾驶专利权诉讼案于近日宣布和解.最终的结果,是Uber向Waymo支付0.34%股权(目前价值2.44亿美元).但事实上,与Uber的官司解决后,一 ...
- python 使用 UTF-8 编码
题记 一般我喜欢用 utf-8 编码,在 python 怎么使用呢? 使用utf-8 文字 在 python 源码文件中用 utf-8 文字.一般会报错,如下: File "F:\works ...
- O2O疯狂烧钱路:止血还是放血好
在国内,无论是互联网巨头还是创业者,很多都将O2O领域当做下一个金矿.而对于很多O2O项目来说,市场规模.用户基数.发展潜力等传统指数依然被当做硬性指标.而为了抢夺用户,很多O2O项目都只能疯狂烧钱, ...
- jquery.form.js笔记
由于项目的原因,需要异步上传文件,网上找了找,很多都是用jquery.form插件的,于是乎找资料,调代码,做点小笔记. 官方资料:http://www.malsup.com/jquery/form/ ...
- OLE DB访问接口“MICROSOFT.JET.OLEDB.4.0”配置为在单线程单位模式下运行,所以该访问接口无法用于分布式
OLE DB访问接口"MICROSOFT.JET.OLEDB.4.0"配置为在单线程单位模式下运行,所以该访问接口无法用于分布式 数据库操作excel时遇到的以上问题的解决方法 解 ...
- Murata村田研发向左,制造向右
前言:Murata村田自1944 年在日本京都创立,是陶瓷无源电子元件.无线连接模块和电源转换技术产品设计和制造领域的全球领导者. Murata 一直在为社会的进步和电子行业的革命贡献自己的力量. 在 ...
- 性能测试之Mysql数据库调优
一.前言 性能调优前提:无监控不调优,对于mysql性能的监控前几天有文章提到过,有兴趣的朋友可以去看一下 二.Mysql性能指标及问题分析和定位 1.我们在监控图表中关注的性能指标大概有这么几个:C ...
- iMX287A基于嵌入式Qt的新冠肺炎疫情监控平台
目录 1.前言 2.数据接口的获取 3.Qt界面的实现 4.在开发板上运行Qt程序 5.最终效果 6.代码下载 @ 1.前言 之前我使用在桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫情数据 ...