​| 作者 梁东阳,数据库研发中心数据库内核工程师,负责腾讯云MySQL的内核开发。


在日常运维中,相信不少人都收藏了很多关于查询优化的方法论和小技巧,但是仔细想想,你真的了解这些优化背后的原理吗?

查询优化器是专门负责优化查询语句的优化器模块,通过计算分析收集的各种系统统计信息,为查询给出最优的执行计划——最优的数据检索方式。

MySQL的优化器主要是将SQL经过语法解析/词法解析后得到的语法树,通过MySQL的数据字典和统计信息的内容,经过一系列运算,从而得出一个执行计划树的构成。之后MySQL按照执行树的要求,计算得出结果。也就是说优化器的输入是一个语法树,输出是一个执行树(也称为执行计划),SQL优化器的具体模块参考如下图:

本篇文章就为大家具体讲解一下各模块具体的功能,让大家对MySQL优化器有更深入的理解。

准备阶段

第一个模块是准备阶段,准备阶段包括如下功能:

名称识别:主要包括将找到并补全对应语句的表名,库名等;

语义检查:通过数据字典如果找不到对应的表名,则直接返回报错;

初级语义变换:主要是根据语义规则,把一些外连接直接转成内连接,子查询EXIST转成IN,然后IN再转成SEMIJOIN等功能。

逻辑变换

逻辑变换也就是在关系代数基础上的变换,变换是为了化简,前后保证结果一致。主要包括:

否定消除:对于多个表达式的和取或析取范式前面有否定的情况,应将关系条件分解成一个一个的,将外面的NOT消除;

等值常量传递:利用了等值关系的传递特性,为了能够尽早执行下推运算(后面会讲到);

常量表达式计算:对于能够立刻计算出结果的表达式,直接计算结果,并将结果与其他条件尽量提前化简。

举例如下:

代价优化准备

基于代价的优化主要是用来确定对于每个表,根据条件是否应用索引,应用哪个索引和确定多表连接的顺序等问题。为了能够进行代价优化,需要尝试各种肯能的方法,从而找到一个代价最小的方法。为了能够比较,就需要给定义一个量化指标。基于代价的优化,主要是为了确定采用如下哪一种方法(如果当前表存在该功能的条件下):

采用哪种索引:一个表可能有主键,也可能有外键,需要根据条件确定使用哪个索引;

确定JOIN顺序:不同的JOIN顺序对性能影响极大;

确定子查询的执行策略:MySQL执行子查询有相当多的方式,究竟哪一个方式更好?

下面介绍一下MySQL的代价模型。一个查询最基础的就是计算两个表JOIN的代价,代价模型就是根据已知信息(元信息,统计信息等)计算该JOIN的代价,即该运算的预估行数*单位代价。

下面介绍代价量化方法。实际上,查询等待主要耗费在CPU和IO上,MySQL将随机读取一个page的消耗定义为1,其他操作的量化指标都是针对该值得对比。不同MySQL版本定义的指标已不尽相同。主要定义指标参考如下:

从源代码里我们可以看到,比如执行一个查询表达式,MySQL实际上是并没有区分具体哪个运算,而是统一给了一个0.1的值,实际上也是不太科学的。

对于范围查询,MySQL会采用如下代价公式,判断究竟是利用全表扫描还是利用索引。

通过EXPLAIN,可以看到不同的条件下MySQL采用了不同的扫描方式,举例参考如下:

确定JOIN顺序

对于有N个表JOIN的查询,实际有N!种可能,如何快速确定采用哪种方法最优,MySQL采用称之为“贪婪算法”的策略,尽可能找到最优路径:

将N个表按照数据量大小和索引有无指标综合排序,小的放前面。并将第一个作为初始表,开始试探;

按照深度遍历算法对后续表进行展开,记录当前最优路径的代价;

如果当前试探部分表的代价大于最优代价,则回溯当前节点,后续也就没必要计算了;

为了防止遍历过多,根据变量optimizer_prune_level,采用是否启用启发式剪枝,即是否需要随机跳过一些节点。

下面通过示例,可以看到确定顺序的流程,参考如下:

索引条件下推

当查询条件都为索引列时,索引条件下推能够将索引条件直接作用于索引上,这样就不需要读取数据文件,将索引数据过滤后的数据读上来,再进行其他条件的过滤,这样能够大大降低非必要的IO操作。

下图展示了索引条件下推与不下推数据流程的不同,具备下推的能够极大减少存储层的IO。

总结

从原来MySQL的只采用基于规则的优化器到目前的基于代价的优化器,实践证明对于大数据量复杂的查询,效果还是比较明显的。同时可也看到随着MySQL8.0的推出,MySQL也加入了一些新指标,比如直方图等,使得代价优化越来越准确,越来越好了。相信这篇文章后使用自己做的查询技巧的时候,也能对背后的原理有一个基本的认知,在工作中更加胸有成竹。

↓↓更多惊喜优惠请点这儿~

云数据库 超值采购专场​cloud.tencent.com

mysql not in优化_98%的人不知道的MySQL优化器原理相关推荐

  1. 你所不知道的MySQL数据库性能优化方案

    一.MySQL数据库引擎的选择 1.1 概述 MySQL数据库中最重要的一个概念就是数据库引擎,不同的数据库引擎的工作原理存在很大差异最终造成MySQL数据库服务的性能差异. 例如如果数据库引擎需要支 ...

  2. mysql架构深入_mysql性能优化2:深入认识mysql体系架构

    前言 本文将重点梳理mysql的体系架构,便于了解mysql的实现原理. Mysql体系结构 Client Connectors 接入方 支持协议很多 Management Serveices &am ...

  3. mysql query 优化_第 8 章 MySQL 数据库 Query 的优化

    前言: 在之前"影响 MySQL 应用系统性能的相关因素"一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 Query 语句的优化 ...

  4. 【技术】作为测试,你应该知道的MySQL知识(二)

    在上一文章<[技术干货]作为测试,你必须知道的MySQL知识(一)>中我们已经学了MySQL基础知识.对于最常用.最重要的select语句将会在本文与大家分享,带你轻松搞定查询语句. 一. ...

  5. mysql group by 天_MySQL group by语句如何优化

    在MySQL中,新建立一张表,该表有三个字段,分别是id,a,b,插入1000条每个字段都相等的记录,如下: mysql> show create table t1G ************* ...

  6. mysql占用cpu_Mysql占用过高CPU时的优化手段(必看)

    Mysql占用CPU过高的时候,该从哪些方面下手进行优化? 占用CPU过高,可以做如下考虑: 1)一般来讲,排除高并发的因素,还是要找到导致你CPU过高的哪几条在执行的SQL,show process ...

  7. mysql架构设计书籍推荐_最近很火的MySQL:抛开复杂的架构设计,MySQL优化思想基本都在这...

    摘要: 冲区才用缓冲区,即SQL_CACHE:sort_buffer_size:排序缓冲区.3)分库分表因为数据库压力过大,首先一个问题就是高峰期系统性能可能会降低,因为数据库负载过高对性能会有影响. ...

  8. MySQL优化系列(二)--查找优化(1)(非索引设计)

    MySQL优化系列(二)--查找优化(1)(非索引设计) 接下来这篇是查询优化,用户80%的操作基本都在查询,我们有什么理由不去优化他呢??所以这篇博客将会讲解大量的查询优化(索引以及库表结构优化等高 ...

  9. 你需要知道的MySQL开源存储引擎TokuDB

    在四月份的Percona Live MySQL会议上, TokuDB庆祝自己成为开源存储引擎整一周年.我现在仍能记得一年前它刚创建时的官方声明与对它的期望.当时的情况非常有意思,因为它拥有帮助MySQ ...

最新文章

  1. 鸟哥学习笔记---网络安全基础
  2. 用数据告诉你王思聪到底有多少钱?
  3. R语言中if else、which、%in%的用法
  4. Java 集合系列(三)Collection 接口
  5. 统计次数c语言,C 语言统计关键字出现次数
  6. 在windows上搭建redis集群(主从复制)
  7. java war包混淆_使用proguard混淆java web项目代码
  8. [黑苹果双系统]macOS 12.4正式版OpenCore/Clover/winPE原版镜像
  9. “当前页面的脚本发生错误”如何解决
  10. 医院招聘计算机人员面试经典问题,医院收费员常见面试题目
  11. 波士顿大学计算机与传媒专业,波士顿大学传媒专业排名如何?
  12. 计算机硬件具体都包含哪些,电脑硬件包括哪些
  13. 三星c7语言设为英文,三星C7手机如何更改显示语言?简单几步就可轻松搞定!
  14. Android文件读写操作(assets 文件、 raw文件、内部存储文件、外部存储文件)
  15. 基于java博网即时通讯软件的设计与实现
  16. 软件测试自学英语语法,5个能力一流的英语自学APP,赶紧盘它,让你告别零基础...
  17. 显示行数 设置ssh终端_mac下终端iTerm2配置
  18. 【Word】docx转doc后公式转换为图片不清晰/模糊
  19. 清华大学计算机系保送,清华北大,保送到外校是什么水平?学姐:总比自己考研强...
  20. Storm之——流组件简单串行编程实践

热门文章

  1. mysql 季度最后一天,MYSQL中取目前年份的第一天和当前周,月,季度的第一天/最后一天...
  2. java生成平滑散点图_【转载】如何在excel制作散点图平滑线散点图
  3. 举例 微积分 拉格朗日方程_变量数学时代——微积分的发明
  4. 织梦tag标签按照设定的栏目id获取相应的内容或自动获取相应栏目tag
  5. VMware vs openStack对比直观优势
  6. 字符串类习题、面试题详解(第二篇)
  7. java web开发中会遇到的异步执行方案
  8. RadioButtonList控件绑定图片Vertical对齐
  9. 聪明的ITPRO之二IT人做事要“圆”
  10. MapGuide应用开发系列(八)----MapGuide Studio准备地图之地图(Map)