手册上查询优化器概述

查询优化器的任务是发现执行SQL查询的最佳方案。大多数查询优化器,包括MySQL的查询优化器,总或多或少地在所有可能的查询评估方案中搜索最佳方案。对于联接查询,MySQL优化器所调查的可能的方案数随查询中所引用的表的数目呈指数增长。对于小数量的表(典型小于7-10),这不是一个问题。然而,当提交的查询更大时,查询优化所花的时间会很容易地成为服务器性能的主要瓶颈。
查询优化的一个更加灵活的方法是允许用户控制优化器详尽地搜索最佳查询评估方案。一般思想是优化器调查的方案越少,它编译一个查询所花费的时间越少。另一方面,因为优化器跳过了一些方案,它可能错过一个最佳方案。
优化器关于方案数量评估的行为可以通过两个系统变量来控制:

  • optimizer_prune_level变量告诉优化器根据对每个表访问的行数的估计跳过某些方案。我们的试验显示该类“有根据的猜测”很少错过最佳方案,并且可以大大降低查询编辑次数。这就是为什么默认情况该选项为on(optimizer_prune_level=1)。然而,如果你认为优化器错过了一个更好的查询方案,则该选项可以关闭(optimizer_prune_level=0),风险是查询编辑花费的时间更长。请注意即使使用该启发,优化器仍然可以探测呈指数数目的方案。

  • ptimizer_search_depth变量告诉优化器对于每个未完成的“未来的”方案,应查看多深,以评估是否应对它进一步扩大。optimizer_search_depth值较小会使查询编辑次数大大减小。例如,如果optimizer_search_depth接近于查询中表的数量,对12、13或更多表的查询很可能需要几小时甚至几天的时间来编译。同时,如果用optimizer_search_depth等于3或4编辑,对于同一个查询,编译器编译时间可以少于1分钟。如果不能确定合理的optimizer_search_depth值,该变量可以设置为0,告诉优化器自动确定该值。
    我们可以通过show variables 来查看这些参数

    备注(手册网址:http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter)

个人理解

从官方手册上看,可以理解为,MySQL采用了基于开销的优化器,以确定处理查询的最解方式,也就是说执行查询之前,都会先选择一条自以为最优的方案,然后执行这个方案来获取结果。在很多情况下,MySQL能够计算最佳的可能查询计划,但在某些情况下,MySQL没有关于数据的足够信息,或者是提供太多的相关数据信息,估测就不那么友好了。
但是感觉手册上,并没有说MySQL怎么去寻找最优方案呢?
通过查询相应的资料,个人理解如下
MySQL优化器中,一个主要的目标是只要可能就是用索引,而且使用条件最严格的索引来尽可能多、尽可能快地排除那些不符合索引条件的数据行,说白了就是选择怎样使用索引,当然优化器还受其他的影响。为了更直观,下面将通过例子来说明。
创建一个表:

CREATE TABLE t8(
id1 INT NOT NULL ,
id2 INT NOT NULL,
KEY id1_key(`id1`),
KEY id2_key(`id2`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;

插入几行数据如下:

当我执行如下查询语句时候,查询优化器会怎样进行优化呢?

select * from t8 where id1=1 and id2=0;

当然,MySQL不会傻到,从t8表中的一行开始,然后一行行的去比较,id1与id2。优化器会先分析数据表,得知有索引id1_key与id2_key,如果先判断id1_key的话,然后需要从4行数据中排除3行数据;如果先判断id2_key的话,然后需要从2行中排除1行。对人来说,这两种方式没有什么区别,但是对于程序而言,先判断id2_key需要较少的计算和磁盘输入输出。因此,查询优化器会规定程序,先去检验id2_key索引,然后在从中挑出id2为0的数据行。
通过下图,我们可以看出,可以选择的索引有id1_key与id2_key,但是实际用到的索引只有id2_key

如果将SQL语句改为 select * from t8 where id1=1 and id2=0;执行情况也是一样的,不区分前后。如下图:

当然,如果将程序,修改为如下

select * from t8 where id1=5 and id2=0;

也可以分析得出,会使用id1_key索引

当然,如果在创建一个复合索引

ALTER TABLE t8 ADD KEY id1_id2_key(`id1`,`id2`)

此时,在此执行select * from t8 where id1=1 and id2=0; 当然会考虑使用id1_id2_key索引。

通过上面的例子,可以理解查询优化器在查询的时候,是选择哪一个索引作为最合适的索引。除此,也提示我们,要慎重选择创建索引。如,上面创建了三个索引(id1_key、id1_key、id1_id2_key),但是优化器优化程序时候,每次只能从中选择一个最合适的,如果创建过多,不仅仅是给数据的更新和插入带来了压力,同时也增加了优化器的压力。

分析优化器优化过程中的信息

其实,在上面已经查看过优化器优化过程中的信息,无非就是使用explain。在这里,在集中说说,里面的参数意义。如下图

id: MySQL Query Optimizer 选定的执行计划中查询的序列号。表示查询中执行 select 子句或操作表的顺序,id值越大优先级越高,越先被执行。id 相同,执行顺序由上至下。
select_type:查询类型,SIMPLE、PRIMARY、UNION、DEPENDENT UNION等。
table:显示这一行的数据是关于哪张表的
type:这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和all
possible_keys:显示可能应用在这张表中的索引。如果为空,没有可能的索引。可以为相关的域从where语句中选择一个合适的语句
key: 实际使用的索引。如果为null,则没有使用索引。很少的情况下,mysql会选择优化不足的索引。这种情况下,可以在select语句中使用use index(indexname)来强制使用一个索引或者用ignore index(indexname)来强制mysql忽略索引
key_len:使用的索引的长度。在不损失精确性的情况下,长度越短越好
ref:显示索引的哪一列被使用了,如果可能的话,是一个常数
rows:mysql认为必须检查的用来返回请求数据的行数
extra:关于mysql如何解析查询的额外信息。

调节MySQL优化器的优化

影响索引的选择

当我们在执行select * from t8 where id1=1 and id2=0; 语句的时候,优化器会id1_id2_key索引,但我们可以通过IGNORE INDEX、 IGNORE INDEX来影响索引的选择

强制索引

通过FORCE INDEX(索引1[,索引2])或者使用USE INDEX(索引1[,索引2]),来指定使用哪个索引,也可以指定多个索引,让优化器从中挑选。

忽略索引

可以使用IGNORE INDEX(索引1[,索引2])来忽略一些索引,这样优化器,就不会考虑使用这些所有,减少优化器优化时间。

影响优化器使用数据表的顺序

一般情况下,MySQL优化器会自行决定按照哪种顺序扫描数据表才能最快地检索出数据,但是我们可以通过STRAGHT_JOIN强制优化器按特定的顺序使用数据表,毕竟优化器做的判断不一定都是最优的。使用原则是,让限制最强的选取操作最先执行。STRAIGHT_JOIN可以放在SELECT后面,也可以放在FROM子句中。
如下图


可以看出,无论from t8,t6还是from t6,t8,都是先检索t6中的表。但是使用STRAIGHT_JOIN的话,就会按照SQL中顺序。

为什么优化器要选择先判断t6中的数据呢?一个主要的原因,因为t6中数据更少。

如果将t8中数据删除几行后,很明显MySQL优化器选择顺序数据表的顺序就会发生变化。

控制SQL语句的优先权

在高并发的网站中,因为MySQL默认的是写优先,有可能导致一些读操作有效时间内得不到执行机会,HIGH_PRIORITY可以使用在selectinsert操作中,让MYSQL知道,这个操作优先进行。

LOW_PRIORITY可以使用在insertupdate操作中,让mysql知道,这个操作将优先权将降低。

INSERT DELAYED告诉MySQL,这个操作将会延时插入。
INSERT DELAYED INTO,是客户端提交数据给MySQL,MySQL返回OK状态给客户端。而这是并不是已经将数据插入表,而是存储在内存里面等待排队。当mysql有空余时,再插入。另一个重要的好处是,来自许多客户端的插入被集中在一起,并被编写入一个块。这比执行许多独立的插入要快很多,因为它较少了I/O操作。坏处是,不能返回自动递增的ID,以及系统崩溃时,MySQL还没有来得及插入数据的话,这些数据将会丢失。

控制查询缓冲

在实际开发中,一些数据对实时性要求特别高,或者并不经常使用(可能几天就执行一次或两次),这样就需要把缓冲关了,不管这条SQL语句是否被执行过,服务器都不会在缓冲区中查找该数据,每次都会从磁盘中读取。因为如果实时性要求特别高,缓存中数据可能和磁盘中的就不同步,如果数据不经常使用,被缓存起来,就会占用内存。
在my.ini中的query_cache_type,使用来控制表缓存的。这个变量有三个取值:0,1,2,分别代表了off、on、demand。
0:表示query cache 是关闭。
1:表示查询总是先到查询缓存中查找,即使使用了sql_no_cache仍然查询缓存,因为sql_no_cache只是不缓存查询结果,而不是不使用查询结果。
2:表示只有在使用了SQL_CACHE后,才先从缓冲中查询数据,仍然将查询结果缓存起来。
我本地缓存是关闭的,,如下图。

关于MySQL缓存可以参考这里
(http://blog.csdn.net/hsd2012/article/details/51526707)

MySQL查询优化器工作原理解析相关推荐

  1. python装饰器原理-Python 装饰器工作原理解析

    #!/usr/bin/env python #coding:utf-8 """ 装饰器实例拆解 """ def login00(func): ...

  2. Python 装饰器工作原理解析

    #!/usr/bin/env python #coding:utf-8""" 装饰器实例拆解 """def login00(func):pr ...

  3. MYSQL查询优化器

    MYSQL 逻辑结构 MySQL 使用典型的客户端/服务器(Client/Server)结构, 体系结构大体可以分为三层:客户端.服务器层以及存储引擎层.其中,服务器层又包括了连接管理.查询缓存 .S ...

  4. mysql查询优化器源码_源码下载网浅析MySQL 查询优化器

    源码下载网浅析MySQL 查询优化器 时间:2019-01-18 17:45作者:网友投稿 优化器(The Optimizer) 这篇描述MySQL查询优化器的工作原理.MySQL查询优化器主要为执行 ...

  5. 揭开SAP Fiori编程模型规范里注解的神秘面纱 - @OData.publish工作原理解析

    Jerry的前一篇文章 揭开SAP Fiori编程模型规范里注解的神秘面纱 - @ObjectModel.readOnly工作原理解析,给大家分享了@ObjectModel.readOnly这个注解对 ...

  6. 转载 调试器工作原理

    调试器工作原理--基础篇 本文是一系列探究调试器工作原理的文章的第一篇.我还不确定这个系列需要包括多少篇文章以及它们所涵盖的主题,但我打算从基础知识开始说起. 关于本文 我打算在这篇文章中介绍关于Li ...

  7. Linux下调试器工作原理

    Linux下调试器工作原理之一-基础篇 介绍关于Linux下的调试器实现的主要组成部分--ptrace系统调用.本文中出现的代码都在32位的Ubuntu系统上开发.请注意,这里出现的代码是同平台紧密相 ...

  8. 调试器工作原理之三——调试信息

    试器工作原理探究系列的第三篇,在阅读前请先确保已经读过本系列的 第一和第二篇. 本篇主要内容 在本文中我将向大家解释关于调试器是如何在机器码中寻找C函数以及变量的,以及调试器使用了何种数据能够在C源代 ...

  9. javascript原理_JavaScript程序包管理器工作原理简介

    javascript原理 by Shubheksha 通过Shubheksha JavaScript程序包管理器工作原理简介 (An introduction to how JavaScript pa ...

最新文章

  1. 吴恩达新书《Machine Learning Yearning》中7个实用建议(附论文)
  2. Linux+nfs配置开机启动,linux NFS配置:NFS开机自动启用及其原理
  3. 2021年8月Web服务器排行榜:Nginx牛市上升
  4. [上下界网络流][二分] Bzoj P2406 矩阵
  5. 4-输出基本数据类型
  6. Java技术回顾之JNDI--JNDI API
  7. Netty工作笔记0026---NIO 网络编程应用--群聊系统1---编写服务器1
  8. 一个没有停止的android闹钟,一旦开始就要把歌唱完 .
  9. spring boot整合jsp报错 Whitelabel Error Page 500或者404 问题处理
  10. 使用Spark SQL读取Hive上的数据
  11. CAD软件中怎么管理设备CAD图层?
  12. 《MySQL DBA:SSL连接》
  13. 【提交】commit
  14. 计算机原理学习(1)
  15. Java开发在线支付平台视频教程(AVI格式)
  16. Python修改私有变量、统计访问次数、华摄氏度转换
  17. dsp2812 pmsm foc之速度环电流环
  18. 优质产品+专业服务 瑞星护航河北省民政厅
  19. 各厂商-链路聚合配置
  20. 评测三款最流行的azw3阅读器(windows适用)

热门文章

  1. 永恒之塔 服务器维护,游戏运行给力永恒之塔更换顶级服务器
  2. 绝地求生刺激战场自定义服务器,绝地求生刺激战场自定义房间怎么创建 自定义房间创建方法...
  3. csgo星空天空代码_csgo代码大全 最实用的CSGO代码
  4. C4D-造型工具笔记
  5. ROS机器人学习——麦克纳姆轮运动学解算
  6. unity之UGUI系统基础
  7. HTML入门 超详细
  8. How to access SMTP/POP server using telnet - 用 Telnet 如何访问邮件服务器
  9. mysql函数输出参数_函数--返回值、参数和作用域
  10. 【CXL】cxl-cli、ndctl、daxctl管理linux内核中NVDIMM设备子系统