设计索引、并让查询使用到索引,只是SQL优化的一部分。

SQL执行计划:

对于涉及到多表的上百行的SQL,每个表都有自己的索引,那么这个SQL跑起来的时候,是如何使用到各个索引,如何读取数据的?

在实际的MYSQL底层,针对磁盘上的大量数据表、聚簇索引、二级索引,如何检索查询,如何筛选过滤、如何使用函数、如何进行排序、分组,这就是SQL执行计划

了解了SQL执行计划,才能进行SQL优化

单表查询的执行计划:

通过explaint + sql语句,查看type字段,来判断是否走了索引:

  • Const:  主键索引,唯一索引
  • Ref: 普通索引,联合索引的等值比较,或是唯一索引或主键索引搞了一个IS NULL/IS NOT NULL
  • Ref_or_null: 普通索引中搞了个IS NULL/IS NOT NULL
  • Range: 普通索引中使用了范围搜索
  • Index:  索引是KEY(x1,x2,x3) 查询是:select x1,x2,x3 from table where x2=xxx,此时没办法使用到联合索引,但是联合索引的字段可以覆盖所有select的字段,所以可以只查找联合索引所在B+树,不需要回表查询
  • All: 全表扫描

Select * from table where x1=xx and x2>=xx,  Index(x1,x3),  Index(x2,x4):

此时,Mysql只能选择一个索引去执行此条SQL,这里MYSQL负责生成执行计划的查询优化器,一般会选择在索引里扫描行数比较少的那个索引。

比如x1,在索引里做等值比较,扫描数据比较少,那么就会挑选Index(x1,x3),做一个索引树的查找(ref),找到几条数据之后,接着做一个回表,回到聚簇索引中找到每条数据的完整数据,接着加载到内存中去,根据每条数据的x2字段的值,根据x2>=xx做一个筛选。

Select * from table where x1=xx and c1=xx and c2>=xx and c3 IS NOT NULL, Index(x1):

此时优化器生成的执行计划中,就仅仅针对x1字段走一个ref访问,直接通过x1字段的索引树找出来一波数据,接着对这波数据都回表查询,然后加载到内存中,接着对c1,c2,c3做过滤和筛选。

Select * from table where x1=xx and x2=xx, Index(x1), Index(x2):

一般情况下,一个SQL语句只能用到一个二级索引。但是如果选择扫描行数最少的那个索引(比如x1)之后,过滤出来的数据量还是有上万条,如果直接回表查询,性能不佳。此时,会同时从x2的索引树中也查出来一波数据,然后做交集之后,数据量会减少很多,此时再做回表查询,性能会提示很多。

多表关联的执行计划:

嵌套循环关联:

有两个表要执行关联,此时会在一个驱动表里根据他的where条件筛出一批数据,然后把这批数据的每一条数据到被驱动表里查找数据,找出来的数据进行关联。类似与Java里面的for循环嵌套。

所以关联表一定不要超过三张。

保证驱动表走索引,同时被驱动表也走索引。

MYSQL如何根据成本优化,选择执行计划的?

把一个数据页从磁盘中读取到内存中的IO成本假定为1.0

在内存中鉴定一条数据是否符合条件的CPU成本假定为0.2

全表扫描的成本:

IO成本:数据页的数量 * 1.0 + 微调值

CPU成本:行记录数量 * 0.2 + 微调值

总成本 = IO成本 + CPU成本

假设一张表有数据2万条,数据页100个,那么全表扫描的总成本 = 100 * 1.0 + 20000 * 0.2 = 4100

二级索引的成本:

1、将二级索引的数据页读取到内存中:因为二级索引存储的字段值很少,一般一个数据页可以存放大量二级索引值,所以可以粗暴的认为,二级索引涉及到N个范围则为N个数据页。IO成本 = 1.0 * 1,或是1.0 * n

2、假设经过二级索引筛选之后,数据量为100,将二级索引的数据页在内存中进行CPU判定,CPU成本 =  0.2 * 数据量 = 0.2 * 100 = 20

3、回表到聚簇索引中,将指定的数据页加载到内存中,由于经过二级索引筛选之后的id值并不连续,所以加载数据页的数量大概等于id值数量,也就是100个数据页,IO成本 = 1.0 * 数据量 = 1.0 * 100 = 100

4、聚簇索引的数据页在内存中进行CPU判定,CPU成本 = 0.2 * 数据量 = 0.2 * 100 = 20

5、总成本 = 1 + 20 + 100 + 20 = 141

MYSQL是如何根据各种规则去优化执行计划的?

其实就是MYSQL对你写的SQL进行重写,从而便于执行。

去括号

常量替换

多表联查时的常量替换

子查询:先查出来子查询的结果集,然后再进行外部查询

IN子查询:先查出来子查询的结果集,然后对结果集数量和外部表数量进行比较,如果子查询结果集数量 > 外部数据表行数,则遍历外部数据表的每个值,去子查询中去判断;反之,则遍历子查询的每个值去外部数据表中去判断。总之,遵循一个原则:驱动表是数据量少的表!外层嵌套的数量值应该小于内层

Mysql内部架构_jerry_dyy的博客-CSDN博客

Mysql存储模型_jerry_dyy的博客-CSDN博客

InnoDB内部架构_jerry_dyy的博客-CSDN博客

Buffer Pool 核心原理_jerry_dyy的博客-CSDN博客

Buffer Pool生产实践_jerry_dyy的博客-CSDN博客

Mysql事务隔离机制_jerry_dyy的博客-CSDN博客

Mysql的锁机制_jerry_dyy的博客-CSDN博客

Mysql的索引深度讲解_jerry_dyy的博客-CSDN博客

Mysql索引的使用_jerry_dyy的博客-CSDN博客

SQL语句的执行计划_jerry_dyy的博客-CSDN博客_sql语句的执行计划

SQL语句的执行计划相关推荐

  1. oracle++spm,ORACLE 11G 使用SPM来调整SQL语句的执行计划

    跟大家说明一下: ITSM 数据库迁移升级到11G后,有几条SQL语句的执行计划不正确,而且这些语句都是使用绑定变量的. 最初的调整想法是获得这些的语句的绑定变量值,将获得的字面值直接替换SQL语句的 ...

  2. 【Oracle】三种方式查看SQL语句的执行计划

    查看执行计划的方式有三种: EXPLAIN PLAN .V$SQL_PLAN .SQL*PLUS AUTOTRACE 1.EXPLAIN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划 ...

  3. 执行计划 分析一条sql语句的效率 mysql_MySQL中一条SQL语句的执行过程

    MySQL中一条SQL语句的执行过程 发布时间:2018-11-24 18:35, 浏览次数:390 , 标签: MySQL SQL 查询语句的执行顺序: 1.客户端通过TCP连接发送连接请求到mys ...

  4. Oracle 高性能SQL引擎剖析----执行计划

    执行计划是指示Oracle如何获取和过滤数据.产生最终结果集,是影响SQL语句执行性能的关键因素.我们在深入了解执行计划之前,首先需要知道执行计划是在什么时候产生的,以及如何让SQL引擎为语句生成执行 ...

  5. 了解Sql Server的执行计划

    前一篇总结了Sql Server Profiler,它主要用来监控数据库,并跟踪生成的sql语句.但是只拿到生成的sql语句没有什么用,我们可以利用这些sql语句,然后结合执行计划来分析sql语句的性 ...

  6. oracle数据库sql的执行过程,Oracle体系结构之SQL语句的执行过程

    一般来说,数据库处理SQL都会经过三个过程:解析(parse).执行(exec).返回结果(fetch) 1.解析 当用户发起一个SQL语句时,Oracle通过Server Process 接收SQL ...

  7. oracle数据库通过SQL profile 绑定SQL最优执行计划(个人实践)

    1.执行SQL语句,同时使用如下命令查找SQL ID select a.SQL_ID,b.SQL_TEXT,b.LAST_LOAD_TIME,b.LAST_ACTIVE_TIME   from v$s ...

  8. SQL Server查询执行计划–基础

    为什么查询执行对SQL Server性能很重要? (Why is query execution important for SQL Server performance?) SQL Server性能 ...

  9. sql查询初学者指南_面向初学者SQL Server查询执行计划–类型和选项

    sql查询初学者指南 When a DBA is working with the SQL Server, he/she might sometimes say that the execution ...

  10. sql查询初学者指南_面向初学者SQL Server查询执行计划–非聚集索引运算符

    sql查询初学者指南 Now that we understand what Clustered Index Scan and Clustered Index Seek are, how they o ...

最新文章

  1. html表格重置标签,HTML——表格标签
  2. Spring的Controller是单例还是多例?怎么保证并发的安全
  3. golang-实现自己的事件驱动
  4. Android 利用源码调试 详解TouchEvent 事件分发机制
  5. NYOJ 士兵杀敌(四) 树状数组
  6. matlab显示像素分布,MATLAb-----7--------如何动态显示鼠标的坐标值和图像像素值
  7. Boost:可移植地自定义boost :: hash的测试程序
  8. IT 企业稿阿米巴 失败
  9. 深度学习之自编码器(2)Fashion MNIST图片重建实战
  10. spring 单例 获取多例的位_Spring系列第6篇:玩转bean scope,避免跳坑里!
  11. node+mongodb+win7
  12. 代码设置margintop_关于内层DIV设置margin-top不起作用的解决方案
  13. 优化vmware mac神器beamoff
  14. esp8266 python 74hc595_十九 ,ESP32 74HC595 的使用
  15. [从头学数学] 第193节 推理与证明
  16. 各个版本JDK官方下载地址
  17. AI玩“剧透”预测《权力的游戏》死亡名单
  18. 最重要的三种能力:思考力、行动力、表达力
  19. 技术天才米勒 oracle,奇迹中的奇迹 WW之功能炫技篇
  20. IDEA try catch快捷键、 快速生成get set 方法快捷键、快速生成有参和无参构造方法快捷键

热门文章

  1. Shell编程语言(一)
  2. 疯狂的程序员 1-10
  3. 万恶的ie(还好只是ie11)
  4. 购物网页设计php实验报告,购物网站设计-Web实验报告
  5. 我爸的电脑中了勒索病毒
  6. oracle循环视频教程,玩转Oracle入门知识和实战教程---韩顺平主讲(全31集)
  7. Storm Player 字幕加载
  8. 【华为 OJ 】成绩排序
  9. 语言学句法分析树形图怎么画_教你如何画语言学树型图
  10. 80G倾斜正射多光谱数据、谷歌影像、各种遥感数据下载