MySQL 5.7下InnoDB对COUNT(*)的优化

简介: MySQL 5.7下InnoDB对COUNT(*)的优化

0、导读

饱受诟病的InnoDB表COUNT(*)性能问题在5.7下做了优化,果真如此吗?

1、经典需求:InnoDB表COUNT(*)

InnoDB引擎表经常被抱怨执行COUNT(*)的效率太差,因此此类需求通常会被建议用其他方法来满足,比如另外加一个计数器表,或者用SHOW TABLE STATUS查看大概数量。

不过,从MySQL 5.7.2起,这个问题得到了解决,我们来看看。

2、MySQL 5.7版本InnoDB对COUNT(*)的优化

MySQL每发布一个新版本,都会放出相应的Release Notes,我们注意到5.7.2版本的发布说明中提到:

InnoDB: SELECT COUNT(*) FROM t statements now invoke a single handler call to the storage engine to scan the clustered index and return the row count to the Optimizer. Previously, a row count was typically performed by traversing a smaller secondary index and invoking a handler call for each record. A single handler call to the storage engine to count rows in the clustered index generally improves SELECT COUNT(*) FROM t performance. However, in the case of a large clustered index and a significantly smaller secondary index, performance degradation is possible compared to performance using the previous, non-optimized implementation. For more information, see Limits on InnoDB Tables.

简单地说就是:COUNT(*)会选择聚集索引,进行一次内部handler函数调用,即可快速获得该表总数。我们可以通过执行计划看到这个变化,例如:

image.png

很明显,在查询优化器阶段就已经得到优化了,相比效率应该杠杠的吧,我们稍后再来对比看看。

补充说下,5.7以前的版本中,COUNT(*)请求通常是:扫描普通索引来获得这个总数。也来看看5.6下的执行计划是怎样的:

image.png

可以看到,可以利用覆盖索引来完成COUNT(*)请求。

3、对比测试

先看一组测试数据:

count(*)对比测试

MySQL 5.6.33

MySQL 5.7.15

相差

表数据量

8976914

9000270

100.26%

耗时(秒)

5.459952

1.142340

20.92%

可以看到,两次数据量相当,但SQL耗时5.7约只有5.6的1/5,这个效率还是不错的吧。

我们来看看5.6和5.7版本下的status和profiling对比情况:

image.png

4、别高兴得太早

看完上面的对比测试,相信您已经心动了吧,但还别高兴得太早哦,官方文档里其实埋了一个伏笔:

InnoDB: SELECT COUNT(*) FROM t statements now invoke a single handler call to the storage engine to scan the clustered index and return the row count to the Optimizer. Previously, a row count was typically performed by traversing a smaller secondary index and invoking a handler call for each record. A single handler call to the storage engine to count rows in the clustered index generally improves SELECT COUNT(*) FROM t performance. However, in the case of a large clustered index and a significantly smaller secondary index, performance degradation is possible compared to performance using the previous, non-optimized implementation. For more information, see Limits on InnoDB Tables.

简言之,就是说如果聚集索引较大(或者说表数据量较大),没有完全加载到buffer pool中的话,有可能反而会更慢,还不如用原先的方式。

下面我们来测试下,读取tpcc测试表stock,该表有1亿行记录,表空间文件约65GB,而innodb buffer pool只分配了12G,这时候再看下对比数据:

count(*)对比测试

MySQL 5.6.33

MySQL 5.7.15

相差

表数据量

1亿

1亿

0.00%

耗时(秒)

693.66

5331.69

768.63%

在这种情况下,5.7版本反而慢的夸张,悲剧啊~

那么在5.7下的大表,有没有办法仍旧采用以前的方法来做COUNT(*)统计呢。当然可以了,我们可以强制指定普通索引,不过还需要加上WHERE条件,否则还是不行。后来搜了下,发现这是个bug,印风(zhaiwx)已经报告给官方了,bug id:81854。

image.png

这次的SQL执行耗时和在5.6下的就基本一样了。

4、后记

5.7版本整体挺赞的,不过还是有不少地方需要完善,期待能更成熟起来。

参考

1. MySQL 5.7.2 Release Notes:http://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-2.html

2. Limits on InnoDB Tableshttp://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html



            </div>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
10月前
|
机器学习/深度学习
RT-DETR改进策略【Conv和Transformer】| CVPR-2024 Single-Head Self-Attention 单头自注意力
RT-DETR改进策略【Conv和Transformer】| CVPR-2024 Single-Head Self-Attention 单头自注意力
126 3
RT-DETR改进策略【Conv和Transformer】| CVPR-2024 Single-Head Self-Attention 单头自注意力
|
10月前
|
机器学习/深度学习 人工智能 监控
AI视频监控在大型商场的智能技术方案
该方案通过目标检测与姿态识别技术(如YOLO、OpenPose),实时监控顾客行为,识别异常动作如夹带物品、藏匿商品等,并结合AI模型分析行为模式,防止偷窃。出口处设置结算验证系统,比对结算记录与视频信息,确保商品全部支付。多角度摄像头和数据交叉验证减少误报,注重隐私保护,提升安保效率,降低损失率,增强顾客信任。
687 15
|
搜索推荐
哪些待办事项App能帮你提高工作效率?
本文介绍了五款受欢迎的待办事项软件:板栗看板、Todoist、Microsoft To Do、Any.do 和 Google Keep。它们各自具备独特的优势,如板栗看板的高效看板模式、Todoist的简洁任务管理、Microsoft To Do的微软生态整合、Any.do的日历整合与团队协作功能,以及Google Keep的简洁界面和云同步。这些工具能有效帮助个人和团队提高任务管理效率。
|
机器学习/深度学习 人工智能 搜索推荐
AI与未来医疗:重塑健康的双刃剑
【10月更文挑战第6天】 人工智能作为现代科技的巅峰之作,已经渗透进我们生活的方方面面。从语音助手到自动驾驶,AI不仅改变了我们的日常,更在各个专业领域,特别是医疗行业,扮演着愈发重要的角色。本文探讨了AI在未来医疗中的应用及其潜在影响,揭示了这把“双刃剑”的机遇与挑战。
429 1
|
缓存 自然语言处理 知识图谱
LLM应用实战:当KBQA集成LLM
项目是关于一个博物馆知识图谱,上层做KBQA应用。实现要求是将传统KBQA中的部分模块,如NLU、指代消解、实体对齐等任务,完全由LLM实现,本qiang~针对该任务还是灰常感兴趣的,遂开展了项目研发工作
310 0
|
存储 网络协议 API
代理ip的使用方法
代理ip的使用方法
385 0
|
XML 存储 安全
微信支付宝支付真的安全吗?为什么没人攻击
微信支付宝支付真的安全吗?为什么没人攻击
微信小游戏制作工具中的分享功能怎么用?
微信小游戏制作工具中的分享功能怎么用?
397 0
|
安全 API 数据安全/隐私保护
阿里云短信服务RAM用户授权Quick Start
短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力。调用API或用群发助手,即可发送验证码、通知类和营销类短信;国内验证短信秒级触达,到达率最高可达99%;国际/港澳台短信覆盖200多个国家和地区,安全稳定,广受出海企业选用。在主账号开通短信服务后,您可以创建RAM用户,并为RAM用户授予不同的权限,提供给您企业的员工用来管理短信服务资源,从而让您避免与其他用户共享云账号密钥,降低您企业的信息安全风险。本文以子账号使用短信服务报错为例,简单介绍主账号授予RAM用户访问使用短信服务的操作步骤,以供参考。
1191 1
阿里云短信服务RAM用户授权Quick Start
办公技巧 | 快速批量制作N张奖状,再也不用加班了!
演示视频中的word文档使用的是16开奖状尺寸,内容的位置已经和奖状对应好,直接可以打印使用。如果你需要,也可以下载下去看看。
456 0