当前位置: 首页 > news >正文

导出 schema_第27问:information_schema.columns 表上做查询慢,为什么?

fadf101152cbabf95dfe2e6b6475686e.png

问题

在 26 问中,我们看到了如下 SQL 在 MySQL 5.7 中跑得很慢:

a7311238338b657522d241ad016eba74.png

我们还分析了执行计划改写后的 SQL,通过猜测,增加了 hint 来解决问题:

b4e2c6b922d7f956e59fdd6a16b2ca9c.png

这一期,我们通过工具来分析一下:MySQL 为什么会使用一个低效的执行计划,以致于我们不得已用 hint 来调优 SQL?

实验

我们接着使用 26 问中的环境,使用 optimizer trace 工具,观察 MySQL 对 SQL 的优化处理过程。

02c792cd64459e151f7f26de99b7ebc0.png

我们先调大 optimizer trace 的内存容量(否则 trace 的输出会被截断),然后开启了optimizer trace 功能。

跑完 SQL 后,可以在 INFORMATION_SCHEMA.OPTIMIZER_TRACE 看到 SQL 的优化处理过程:

69e640ee03368953e356437593f1e813.png

这会是个巨大的 json,我们将其复制出来,找个 json 的可视化编辑器来分析一下。


小贴士

如果 MySQL 启动时有配置 --secure-file-priv,那可以用,

SELECT TRACE INTO DUMPFILE  FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

将 trace 导出到文件里,会更方便一些。

这里我们选择了一个在线的 json 编辑器,使用起来会方便一点:

b57910f8480503c22befea91a9c96643.png

可以看到整个优化过程分为 6 个步骤,前两步都跟创建临时表相关,然后是 join 的准备工作,再是两步 join 优化,最后是 join 的执行。

回忆一下 26 问中,我们的子查询应使用物化方式,但实际使用了 exists 子句方式,我们猜测这个选择是在 join 的优化阶段做出的。

仔细翻一翻,就会找到可疑的部分:

4d32a6d0a8efaf86c22aa8cf49278b70.png

上图中的中文,是从英文翻译过来的。看上去我们找对了位置。

接下来我们逐步看看这个决策的依据是什么:

5e7348a01d7a516f4b315032805553dc.png

显然不物化的代价更小,那么优化器选择不物化是正确的选择。

但使用 exists 子句进行子查询的代价,显然不可能为 0,MySQL 对这个代价的计算可能有误。

我们得来看看 MySQL 是如何计算这个代价的:

c704e4c0a883b90a428555733c3c0d5a.png

执行 exists 子查询的代价 = 执行一次子查询的代价 * 子查询需要执行的次数

显然这个子查询不可能只需要执行 0 次

这里需要做一个额外的思考:在这个场景下,子查询需要执行的次数,与父查询的行数相同。

9bb3278cacae8eee5181ffef1ec23f56.png

也就是红框内需要执行的次数,取决于红框外的 SQL 的结果集条数。

8c2e5432f6375b21f7a10932cefb4b56.png

这里 MySQL 将父表的结果集条数 称为 "扇出度"(fanout)

显然,这里父表 information_schema.columns 的扇出度为 0,直接导致了优化器放弃了物化的策略

那 information_schema.columns 的扇出度为什么是 0 呢?

75a24a2d0976f47f3d7462710cd7bfcb.png

查看 information_schema.tables 中对于 COLUMNS 表的描述,我们看到 MySQL 将 information_schema 中的元数据表做了特殊对待,其行数估计是没有意义的。

到此我们找到了问题所在:MySQL 5.7 对元数据表使用了区别设计,与普通表的行数估算方式不同。

以后大家在 MySQL 5.7 中使用 information_schema 中的元数据表做复杂查询时,需要额外注意执行计划,可能需要使用 hint 指导优化器工作。


小贴士

MySQL 8.0 中进行了数据字典的改造,information_schema 中的元数据表大部分都变成了视图,其真实的数据源是 mysql 库中的隐藏元数据表。

对 MySQL 8.0 的元数据表进行复杂查询,执行计划会比 MySQL 5.7 更加合理。
相关推荐:

第26问:information_schema.columns 表上做查询慢,怎么办?

第25问:MySQL 崩溃了,打印了一些堆栈信息,怎么读?

第24问:一主多从的半同步复制,到底是哪个 slave 拖慢了性能?
关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!

0dbf2de978da069d575c8e0a30bf823a.png

本文关键字:#information_schema#  #优化器# #hint# 想看更多技术好文,点个 “在看” 吧!

相关文章:

  • 单相交流调压matlab_电力线路工熟知单相、三相变压器原理详解
  • 陈硕智能指针线程安全_「C++基础篇」智能指针 auto_ptr/unique_ptr/shared_ptr
  • easyui是否容易上手_bootstrap 和 jQueryEasyUI 哪个做后台管理系统更好一些?
  • column分栏布局只是文字布局吗_写给自己看的CSS columns分栏布局教程
  • 定时备份mysql脚本_自动定时备份 mysql 数据库 的 shell 脚本
  • mysql存储xml_mysql存储xml数据 mysql和sql server
  • 使用php mysql js实现聊天功能_php实现简单聊天功能
  • 帝国cms与mysql数据库_如何使用帝国CMS自带的数据库类
  • mysql所有选修课程都及格_MySQL 练习题目 二刷 - 2019-11-4 5:55 am
  • c3p0连接池配置 mysql_C3P0连接池配置详解 + 数据库主从配置
  • mysql查看字符出现次数_mysql 查找一个列中,一个字符出现的次数
  • windows 发包工具_ksubdomain 无状态域名爆破工具
  • epel mysql_RHEL/CentOS 6.x使用EPEL6与remi的yum源安装MySQL 5.5.x
  • j2ee mysql struts_j2ee 整合 struts2.3.4
  • mysql加快备份_mysqldump 备份直接至压缩文件,提高备份及压缩时间
  • 《剑指offer》分解让复杂问题更简单
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • 【前端学习】-粗谈选择器
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • 2017届校招提前批面试回顾
  • es6--symbol
  • Git 使用集
  • Java面向对象及其三大特征
  • scala基础语法(二)
  • SpiderData 2019年2月25日 DApp数据排行榜
  • vue学习系列(二)vue-cli
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从零开始学习部署
  • 翻译:Hystrix - How To Use
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 通过git安装npm私有模块
  • 温故知新之javascript面向对象
  • 由插件封装引出的一丢丢思考
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • ​ArcGIS Pro 如何批量删除字段
  • #pragma 指令
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (二十四)Flask之flask-session组件
  • (规划)24届春招和25届暑假实习路线准备规划
  • (七)c52学习之旅-中断
  • (一)认识微服务
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .net和jar包windows服务部署
  • .NET命令行(CLI)常用命令
  • @Bean有哪些属性
  • @RequestBody与@ModelAttribute
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解
  • [ 代码审计篇 ] 代码审计案例详解(一) SQL注入代码审计案例
  • [17]JAVAEE-HTTP协议
  • [23] GaussianAvatars: Photorealistic Head Avatars with Rigged 3D Gaussians
  • [Bzoj4722]由乃(线段树好题)(倍增处理模数小快速幂)