[MySQL 5.6] 初识5.6的optimizer trace

在MySQL5.6中,支持将执行的SQL的查询计划树记录下来,目前来看,即使对于非常简单的查询,也会打印出冗长的查询计划,看起来似乎不是很可读,不过对于一个经验丰富,对查询计划的生成过程比较了解的DBA而言,这是一个优化SQL的宝藏,因为暴露了大量的内部产生查询计划的信息给用户,这意味着,我们可以对开销较大的部分进行优化。

新参数optimizer_trace可以控制是否为执行的SQL生成查询计划树,默认关闭,我们也建议关闭,因为它会产生额外的性能开销(dimitrik的评测:http://dimitrik.free.fr/blog/archives/2012/01/mysql-performance-overhead-of-optimizer-tracing-in-mysql-56.html)。

我在自己的机器上使用sysbench测试,64个并发,select.lua,纯内存操作,QPS从112,000下降到88,000。

这是session级别的参数,如果需要是,可以在session级别打开,线程只能看到当前会话的查询计划,无法看到其他会话的。

使用也很简单:

打开optimizer_trace

mysql> set session optimizer_trace=’enabled=on‘;

Query OK, 0 rows affected (0.00 sec)

<执行你的SQL>  (例如,这里执行select * from sbtest1 order by k limit 3;)

然后查询information_schema.optimizer_trace表,输出如下

| select * from sbtest1 order by k limit 3 | {

“steps”: [

{

“join_preparation”: {

“select#”: 1,

“steps”: [

{

“expanded_query”: “/* select#1 */ select `sbtest1`.`id` AS `id`,`sbtest1`.`k` AS `k`,`sbtest1`.`c` AS `c`,

`sbtest1`.`pad` AS `pad` from `sbtest1` order by `sbtest1`.`k` limit 3″

}

]

}

},

{

“join_optimization”: {

“select#”: 1,

“steps”: [

{

“table_dependencies”: [

{

“table”: “`sbtest1`”,

“row_may_be_null”: false,

“map_bit”: 0,

“depends_on_map_bits”: [

]

}

]

},

{

“rows_estimation”: [

{

“table”: “`sbtest1`”,

“table_scan”: {

“rows”: 986400,

“cost”: 13741

}

}

]

},

{

“considered_execution_plans”: [

{

“plan_prefix”: [

],

“table”: “`sbtest1`”,

“best_access_path”: {

“considered_access_paths”: [

{

“access_type”: “scan”,

“rows”: 986400,

“cost”: 211021,

“chosen”: true

}

]

},

“cost_for_plan”: 211021,

“rows_for_plan”: 986400,

“chosen”: true

}

]

},

{

“attaching_conditions_to_tables”: {

“original_condition”: null,

“attached_conditions_computation”: [

],

“attached_conditions_summary”: [

{

“table”: “`sbtest1`”,

“attached”: null

}

]

}

},

{

“clause_processing”: {

“clause”: “ORDER BY”,

“original_clause”: “`sbtest1`.`k`”,

“items”: [

{

“item”: “`sbtest1`.`k`”

}

],

“resulting_clause_is_simple”: true,

“resulting_clause”: “`sbtest1`.`k`”

}

},

{

“refine_plan”: [

{

“table”: “`sbtest1`”,

“access_type”: “table_scan”

}

]

},

{

“reconsidering_access_paths_for_index_ordering”: {

“clause”: “ORDER BY”,

“index_order_summary”: {

“table”: “`sbtest1`”,

“index_provides_order”: true,

“order_direction”: “asc”,

“index”: “k”,

“plan_changed”: true,

“access_type”: “index_scan”

}

}

}

]

}

},

{

“join_execution”: {

“select#”: 1,

“steps”: [

]

}

}

]

}

###############################################################

主要分为三个部分

join_preparation:SQL的准备阶段,sql被格式化

对应函数 JOIN::prepare

例如 * 被扩展开来

join_optimization:SQL优化阶段

对应函数JOIN::optimize

join_execution:SQL执行阶段

对应函数:JOIN::exec

可以看到,即便是一条非常简单的SQL,也会打印出很冗长的查询计划。

当然你也可以把查询计划导入到文件中去,例如导入到一个命名为xx.trace的文件,然后用JSON阅读器来查看

SELECT TRACE INTO DUMPFILE “xx.trace” FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

官方文档给出了一个不错的例子,比这里的这个要复杂多了,有兴趣的同学可自行翻阅:http://dev.mysql.com/doc/internals/en/tracing-example.html

之前也写过博客,提及到optimizer trace的相关选项(http://mysqllover.com/?p=470 ):

optimizer_trace有两个字段:

“enabled=on,one_line=off” ,可以通过set 进行字符串更新,前者表示打开optimizer_trace,后者表示打印的查询计划是否以一行显示,还是以json树的形式显示

我们可以在session级别来设这这个参数。

默认optimizer_trace_limit值为1,因此只会保存一条记录。这个设置需要重连session才能生效,另外一个变量optimizer_trace_offset通常与之配合使用,默认值为-1

例如,offset=-1, limit=1将显示最近一次trace

offset=-2,limit=1将显示最近的前一个trace。

offset=-5,limit=5 将最近的5次trace打印出来

总的来说:

当offset大于0时,则会显示老的从offset开始的limit个trace,也就是说,新的trace没有记下来。

当offset小于0时,则会显示最新的-offset开始的limit个trace,也就是说,只显示新的trace

注意重设变量会导致trace被清空

另外由于trace数据是存储在内存中的,因此还需要设置optimizer_trace_max_mem_size来限制内存的使用量,否则意外的设置可能导致内存爆掉。这是session级别,不应该设置的过大

optimizer_trace_limit和optimizer_trace_offset也影响占用内存大小,但不应该超过OPTIMIZER_TRACE_MAX_MEM_SIZE

另外,还有个参数optimizer_trace_features,可以控制打印到查询计划树的项,默认情况下是全部打开的,如下:

mysql> show variables like ‘optimizer_trace_features‘;

+————————–+—————————————————————————-+

| Variable_name            | Value                                                                      |

+————————–+—————————————————————————-+

| optimizer_trace_features | greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on |

+————————–+—————————————————————————-+

1 row in set (0.00 sec)

如果你不关心某些查询计划选项,可以将其关闭掉,只打印你关注的,这样可以减小查询计划树的输出,让其更可读一点。

greedy_search:对于有N个表的join操作,可能产生N的阶乘的查询计划路径;

range_optimizer:range优化

dynamic_range:dynamic range optimizer(也就是”range checked  for each row”,每个外部列会执行一次range optimizer);如果关闭该选项的话,只有第一次调用JOIN_TAB::SQL_SELECT才被跟踪

repeated_subselect:子查询,如果关闭的话,只有第一次调用Item_subselect 才被跟踪

—————————————————-

TODO PLAN:增加阈值(读取的行数,或者执行的时间),超过阈值时,自动将trace导入到某个文件中,这样可以便于在线debug

参考:

http://dev.mysql.com/doc/internals/en/optimizer-features-to-trace.html

http://dev.mysql.com/doc/internals/en/system-variables-controlling-trace.html

http://guilhembichot.blogspot.com/2011/09/optimizer-tracing-how-to-configure-it.html

http://jorgenloland.blogspot.com/2011/10/optimizer-tracing-query-execution-plan.html

原创文章,转载请注明: 转载自Simple Life

本文链接地址: [MySQL 5.6] 初识5.6的optimizer trace

文章的脚注信息由WordPress的wp-posturl插件自动生成

时间: 2024-12-24 07:17:33

[MySQL 5.6] 初识5.6的optimizer trace的相关文章

MYSQL之数据库初识、安装详解、sql语句基本操作

目录 MYSQL之数据库初识及安装详解 1.什么是数据库? 1.什么是数据?(data) 2.什么是数据库?(databases,简称DB) 2.为什要用数据库? 3.什么是数据库管理系统?(DataBase Management System 简称DBMS) 4.数据库管理软件的分类 5.MYSQL数据库 6.数据库服务器.数据管理系统.数据库.表记录之间的关系 MYSQL的安装 下载及启动 配置环境变量及作系统服务 修改密码 破解密码 配置文件 数据库的基本操作 MYSQL之数据库初识及安装

编程之路:MySql系列之初识

数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件都运行在一台机器上,那么用文件存取数据,并没有问题. 很不幸,这些假设都是你自己意淫出来的,上述假设存在以下几个问题...... 1.程序所有的组件就不可能运行在一台机器上 #因为这台机器一旦挂掉则意味着整个软件的崩溃,并且程序的执行效率依赖于承载它的硬件,而一台机器机器的性能总归是有限的,受限于目前的

MySQL(1):初识SQL

一.前言 MySQL :是用于管理数据的软件 MySQL是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性. 分为服务端和客户端(也是基于C/S架构的程序) 服务端: socket服务端 本地文件操作 解析指令(SQL语句) 客户端: socket客户端 发送指令 解析指令(SQL语句) 需要掌握 安装服务端和客户端    https://www.mysql.com 连接 学习SQL语句规则,指示服务端做相应的操作 其他了

mysql 排序

一.主要内容简介 MySQL排序是个老生长谈的话题,这次我们想由浅入深详细说说MySQL的几种排序模式,怎么选择不同排序模式,以及如何优化排序. 同时也希望通过本文能解决大家的几个疑问: MySQL什么时候做排序,怎么判断需要进行排序: MySQL有几种排序模式,有什么方法让MySQL选择不同的排序模式: MySQL排序跟 read_rnd_buffer_size 有啥关系,在哪些情况下增加 read_rnd_buffer_size 能优化排序效率: 怎么判断MySQL使用了磁盘排序,怎么避免或

mysql Tracing the Optimizer

背景:做为一个DBA,或者从事数据库相关工作的小伙伴,常见的工作就是优化sql,查看执行计划!但有时优化器给出的执行计划是错误或者不是最优的, 这时我们就要去追踪一下优化执行计划生成的过程.mysql 5.6提供了Tracing the Optimizer 功能这可是优化sql的一大神器 一,开启Tracing the Optimizer set optimizer_trace_max_mem_size=300000;set end_markers_in_json=true;SET optimi

初识php 环境的配置和简单的get post

搭建服务器环境用  apache 地址下载 数据库mysql 安装php 初识php 环境的配置和简单的get post,布布扣,bubuko.com

mysql 执行计划分析三看, explain,profiling,optimizer_trace

http://blog.csdn.net/xj626852095/article/details/52767963 step 1 使用explain 查看执行计划, 5.6后可以加参数 explain format=json xxx 输出json格式的信息 step 2  使用profiling详细的列出在每一个步骤消耗的时间,前提是先执行一遍语句. #打开profiling 的设置 SET profiling = 1; SHOW VARIABLES LIKE '%profiling%'; #查

提示&quot;Zend Optimizer not installed&quot;卸载安装也不行,什么原因如何解决?

如题:Zend Optimizer not installed可能原因及解决方法 Optimizer, Zend 在配置php服务器的时候,所有的东西都安装好了,就是浏览一个要求zend的程序的时候,总是提示"Zend Optimizer not installed",卸载重新安装也不行,很是郁闷.网上搜索了一下,有这个问题的也很多,下面是摘录的一些解决方法:1. Zend,而安装完成后却发现"Zend Optimizer not installed",经过一番对比

MySQL追踪优化器小试

首先看一下MySQL追踪优化器的典型用法: 打开:SET optimizer_trace="enabled=on"; 查询优化器的信息:SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE; 关闭:SET optimizer_trace="enabled=off"; 默认情况下是关闭的,要使用的时候一定要打开这个优化器. 看一下参数: enabled:打开或者关闭跟踪器 one_line:如果ON的话将会以JOSN的存储方