首先看一下MySQL追踪优化器的典型用法:
打开:
SET optimizer_trace="enabled=on";
查询优化器的信息:mysql
SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
关闭:sql
SET optimizer_trace="enabled=off";
默认状况下是关闭的,要使用的时候必定要打开这个优化器。json
看一下参数:
enabled:打开或者关闭跟踪器
one_line:若是ON的话将会以JOSN的存储方式保存跟踪,可是阅读的话就是比较费劲的,除了能节省空间没啥好处,不过仍是建议使用这个方式。
看一下优化器的相关参数,也可使用mysqld --verbose --help查看:
--optimizer-trace=name 控制优化的跟踪
--optimizer-trace-features=name Enables/disables tracing of selected features of the Optimizer: optimizer_trace_features=option=val[,option=val...], where option is one of {greedy_search, range_optimizer, dynamic_range, repeated_subselect} and val is one of {on, off, default}
--optimizer-trace-limit=# 显示优化追踪器的最大数量
--optimizer-trace-max-mem-size=# 存储优化的痕迹容许的最大尺寸累积
--optimizer-trace-offset=# Offset of first optimizer trace to show; see manual --end-markers-in-json=#
In JSON output ("EXPLAIN FORMAT=JSON" and optimizer trace), if set to 1, repeats the structure's key (if it has one) near the closing bracke
并且这个是和前面所说的information_schema.OPTIMIZER_TRACE表是相对应的
SET GLOBAL optimizer_trace="one_line=on";
打开追踪优化器优化
而后作一条操做就能看到具体的追踪优化器的信息了,经过如下的语句进行查询:
select * from information_schema.OPTIMIZER_TRACE\G;
看一下这张表的结构:spa
看一下字段信息:
QUERY :查询语句
TRACE :跟踪信息,是以JSON形式存储的
MISSING_BYTES_BEYOND_MAX_MEM_SIZE:
INSUFFICIENT_PRIVILEGES
追踪优化器能够跟踪不少信息,SELECT insert,replace(其值或选择) ; UPDATE / DELETE和multi-table variants;全部EXPLAIN前缀之前的; SET(除非它操纵optimizer_trace系统变量) ;作; DECLARE / CASE / IF / RETURN(存储程序语言元素) ;call。若是这些语句之一被制备并在分开的步骤中执行,preparation 和execution单独跟踪
通常状况下,一个新的跟踪都会覆盖掉之前的跟踪,特别是对于执行的语句,只能在最新的跟踪器中生成,老的跟踪器是不会产生的,这就是覆盖原则。因此咱们须要对追踪优化器进行净化。看一下下面的语句:
SET optimizer_trace_offset=<OFFSET>, optimizer_trace_limit=<LIMIT>
经过上面的语句进行净化。optimizer_trace_offset和optimizer_trace_limit的默认值分别为-1和1.这个参数设置指的是什么呢:
1:当用户退出后全部的跟踪信息都会被清除
2:若是OFFSET 是大于0的相同的查询会返回到第一次查询的记录信息,OFFSET 是小于0的话这条记录就会被记录下来。
例如咱们将设置如下信息的话:
OFFSET=-1 and LIMIT=1 最后一次查询信息将会被记录下来
OFFSET=-2 and LIMIT=1将会记录下一个到最后的查询信息
OFFSET=-5 and LIMIT=5 将会记录最后五次查询信息
OFFSET=0 and LIMIT=5 只会记录五次信息
OFFSET≥0的时候,内存中只会记录LIMIT调跟踪信息
SET optimizer_trace_offset=-5, optimizer_trace_limit=5;
多个语句执行N次N大于5在进行查询:debug
SELECT * FROM information_schema.OPTIMIZER_TRACE;

能够看到只是记录了最后的五条信息而已。
官网给出了建议的查询语句:
SELECT * FROM OPTIMIZER_TRACE LIMIT LIMIT OFFSET OFFSET ;
并且咱们还能够经过如下语句监控到使用的内存究竟是多少:3d
show variables like 'optimizer_trace_max_mem_size';

并且OPTIMIZER_TRACE表的MISSING_BYTES_BEYOND_MAX_MEM_SIZE这个列还会记录到当前语句丢失了多少内存,而咱们经过show variables like 'optimizer_trace_max_mem_size';查找的内存使用信息每每是和真是的偏小一点,真实内存使用每每要高。
OPTIMIZER_TRACE表的INSUFFICIENT_PRIVILEGES是用来查看权限的,当一些复杂的语句,可是查看跟踪的用户缺乏权限的时候,这列值每每将显示为1。这就表示实际上是没有权限的。
并且要记住一点就是跟踪器的事件若是被记录下来的话,那么也是会被自动记录到 --debug file当中的.
咱们知道跟踪器的话是以JOSN存储trace的,可是JOSN的格式是很难阅读的,因此说MySQL有了如下的参数:
end_markers_in_json这个变量:
root@localhost [information_schema]>show variables like 'end_markers_in_json';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| end_markers_in_json | OFF |
+---------------------+-------+
1 row in set (0.01 sec)
下面设置如下setting @@end_markers_in_json=on;打开参数之后再去查询的话就会方便的多(这个参数是5.7特有的):code
或者咱们使用EXPLAIN FORMAT=JSON也能够达到相同的结果。
那么问题来了,优化跟踪器有哪些特色呢,跟踪优化器能够避免屡次跟踪同一个语句,这样就不会形成跟踪文件的疯狂增加。跟踪优化器主要有如下的特色:
懒查询:这样的话一个JOIN语句有N个表,最多只会产生N阶乘个执行计划
动态范围跟踪:只输出检查范围内的记录,范围内记录只会从新运行一次,可是没有运行过的记录就会从新生成一个计划。
子查询:每一个字查询只会运行一次
这些功能咱们是能够本身设置的:>show variables like 'optimizer_trace_features';
咱们能够看一下跟踪的记录信息,可能会有点乱:
join-preparation 准备
join-optimization优化对象
join-execution最后执行
以及调用的范围内优化,成本评估,为何选择在另外一个的访问路径,为何仍是选择了另一个排序方法,显示过的缘由。距离显示一切都在发生优化远,但咱们计划显示将来更多的信息。因为截图很乱,不知道大家看获得不,体验眼力劲的时候出现了。固然也能够经过前面的方式修改一下格式看一下可能更加的乐观。
咱们最好将跟踪记录而且导出到文件,这样看起来更加好看
SELECT TRACE FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE into outfile'/var/lib/mysql-files/dump.sql';
若是想要其余人看不到本身的跟踪信息,必定要记得打开如下的参数:orm
--maximum-optimizer-trace-max-mem-size=0 --optimizer-trace-max-mem-size=0