用MySQL的optimizer_trace进行sql调优

在我们调优MySQL的SQL时候,通常使用三种工具进行查看sql执行的效率,explain、profile、optimizer_trace。前两个经常被人使用,由于第三个难度较大,大家使用的较少,下面简单说下如何使用。

opitimizer_trace的使用:

# 开启跟踪,默认是关闭的

SET optimizer_trace="enabled=on";

#执行你的sql语句

select ....

#查看trace信息

SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

# 执行完你需要的sql语句就可以关闭trace了

SET optimizer_trace="enabled=off";

支持的trace语句有:

1.SELECT;

2.INSERT or REPLACE (with VALUES or SELECT);

3.UPDATE/DELETE and their multi-table variants;

4.all the previous ones prefixed by EXPLAIN;

5.SET (unless it manipulates the optimizer_trace system variable);

6.DO;

7.DECLARE/CASE/IF/RETURN (stored routines language elements);

8.CALL.

如下这个语句可以把结果插入到一个文件里:

SELECT TRACE INTO DUMPFILE <filename> FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

在mysqld里进行设置相关参数:

A brief overview from "mysqld --verbose --help":

--optimizer-trace=name

Controls tracing of the Optimizer:

--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=#

Maximum number of shown optimizer traces

--optimizer-trace-max-mem-size=#

Maximum allowed cumulated size of stored optimizer traces

--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 bracket

 具体跟踪的json格式的信息:

select * from test1,test2 where test1.id=test2.id and test1.id>4999900 | {

"steps": [

{

"join_preparation": {           --连接准备

"select#": 1,                 --join准备的第一步

"steps": [                    --解析成编号,解析数据库和表

{

"expanded_query": "/* select#1 */ select `test1`.`id` AS `id`,`test1`.`k` AS `k`,`test1`.`c` AS `c`,`test1`.`pad` AS `pad`,`test2`.`id` AS `id`,`test2`.`k` AS `k`,`test2`.`c` AS `c`,`test2`.`pad` AS `pad` from `test1` join `test2` where ((`test1`.`id` = `test2`.`id`) and (`test1`.`id` > 4999900))"

}

]

}

},

{

"join_optimization": {         --join优化

"select#": 1,

"steps": [

{

"condition_processing": {       --where条件

"condition": "WHERE",

"original_condition": "((`test1`.`id` = `test2`.`id`) and (`test1`.`id` > 4999900))",

"steps": [       --优化的步骤

{

"transformation": "equality_propagation",         --等值优化

"resulting_condition": "((`test1`.`id` > 4999900) and multiple equal(`test1`.`id`, `test2`.`id`))"   --把test.id>4999900放到前面,test1.id=test2.id使用多等值连接

},

{

"transformation": "constant_propagation",        --常量优化

"resulting_condition": "((`test1`.`id` > 4999900) and multiple equal(`test1`.`id`, `test2`.`id`))"

},

{

"transformation": "trivial_condition_removal",   --琐碎的条件排除

"resulting_condition": "((`test1`.`id` > 4999900) and multiple equal(`test1`.`id`, `test2`.`id`))"

}

]

}

},

{

"table_dependencies": [     --表依赖

{

"table": "`test1`",        --表名

"row_may_be_null": false,  --是否有null值,flase是没有

"map_bit": 0,

"depends_on_map_bits": [

]

},

{

"table": "`test2`",

"row_may_be_null": false,

"map_bit": 1,

"depends_on_map_bits": [

]

}

]

},

{

"ref_optimizer_key_uses": [    --相关优化索引使用

{

"table": "`test1`",

"field": "id",             --索引字段

"equals": "`test2`.`id`",  --连接的等值字段

"null_rejecting": false

},

{

"table": "`test2`",

"field": "id",

"equals": "`test1`.`id`",

"null_rejecting": false

}

]

},

{

"rows_estimation": [          --行评估

{

"table": "`test1`",

"range_analysis": {          --范围分析

"table_scan": {

"rows": 4804854,          --4804854行数据

"cost": 1.03e6            --花费1.03e6

},

"potential_range_indices": [   --可能的范围指数

{

"index": "PRIMARY",

"usable": true,           --可使用的索引

"key_parts": [

"id"

]                         --可使用的索引字段

},

{

"index": "k_1",

"usable": false,         --不能使用的索引

"cause": "not_applicable"  --不被应用

}

],

"setup_range_conditions": [     --设置范围条件

],

"group_index_range": {          --组范围索引

"chosen": false,              --不选择的

"cause": "not_single_table"   --goup by不是一个表的,所以不选择

},

"analyzing_range_alternatives": {     --分析每个索引做范围扫描的花费

"range_scan_alternatives": [       --范围扫描花费

{

"index": "PRIMARY",

"ranges": [

"4999900 < id"

],

"index_dives_for_eq_ranges": true,    --索引驱动等值范围扫描

"rowid_ordered": true,                --rowid是顺序的

"using_mrr": false,                   --不能使用mrr,因为是主键

"index_only": false,

"rows": 99,                           --过滤出来99行

"cost": 21.434,                       --花费21.434

"chosen": true                        --这个索引被选择选择

}

],

"analyzing_roworder_intersect": {         --分析执行顺序阶段

"usable": false,                        --不可使用

"cause": "too_few_roworder_scans"       --少数的执行顺序扫描

}

},

"chosen_range_access_summary": {           --选择范围访问概述

"range_access_plan": {

"type": "range_scan",

"index": "PRIMARY",

"rows": 99,

"ranges": [

"4999900 < id"

]

},

"rows_for_plan": 99,

"cost_for_plan": 21.434,

"chosen": true

}

}

},

{

"table": "`test2`",

"range_analysis": {

"table_scan": {

"rows": 4804854,

"cost": 1.03e6

},

"potential_range_indices": [

{

"index": "PRIMARY",

"usable": true,

"key_parts": [

"id"

]

},

{

"index": "k_2",

"usable": false,

"cause": "not_applicable"

}

],

"setup_range_conditions": [

],

"group_index_range": {

"chosen": false,

"cause": "not_single_table"

},

"analyzing_range_alternatives": {

"range_scan_alternatives": [

{

"index": "PRIMARY",

"ranges": [

"4999900 < id"

],

"index_dives_for_eq_ranges": true,

"rowid_ordered": true,

"using_mrr": false,

"index_only": false,

"rows": 99,

"cost": 21.433,

"chosen": true

}

],

"analyzing_roworder_intersect": {

"usable": false,

"cause": "too_few_roworder_scans"

}

},

"chosen_range_access_summary": {

"range_access_plan": {

"type": "range_scan",

"index": "PRIMARY",

"rows": 99,

"ranges": [

"4999900 < id"

]

},

"rows_for_plan": 99,

"cost_for_plan": 21.433,

"chosen": true

}

}

}

]

},

{

"considered_execution_plans": [   --决定执行计划

{

"plan_prefix": [             --计划前

],

"table": "`test1`",          --test1表的执行计划

"best_access_path": {        --最好的访问路径

"considered_access_paths": [  --决定的访问路径

{

"access_type": "ref",     --访问类型是ref

"index": "PRIMARY",       --使用的索引是主键

"usable": false,

"chosen": false

},

{

"access_type": "range",

"rows": 99,

"cost": 41.234,

"chosen": true

}

]

},

"cost_for_plan": 41.234,

"rows_for_plan": 99,

"rest_of_plan": [

{

"plan_prefix": [

"`test1`"

],

"table": "`test2`",

"best_access_path": {

"considered_access_paths": [

{

"access_type": "ref",

"index": "PRIMARY",

"rows": 1,

"cost": 99.2,

"chosen": true

},

{

"access_type": "range",

"cause": "heuristic_index_cheaper",

"chosen": false

}

]

},

"cost_for_plan": 160.03,

"rows_for_plan": 99,

"chosen": true

}

]

},

{

"plan_prefix": [

],

"table": "`test2`",

"best_access_path": {

"considered_access_paths": [

{

"access_type": "ref",

"index": "PRIMARY",

"usable": false,

"chosen": false

},

{

"access_type": "range",

"rows": 99,

"cost": 41.233,

"chosen": true

}

]

},

"cost_for_plan": 41.233,

"rows_for_plan": 99,

"rest_of_plan": [

{

"plan_prefix": [

"`test2`"

],

"table": "`test1`",

"best_access_path": {

"considered_access_paths": [

{

"access_type": "ref",

"index": "PRIMARY",

"rows": 1,

"cost": 99.2,

"chosen": true

},

{

"access_type": "range",

"cause": "heuristic_index_cheaper",

"chosen": false

}

]

},

"cost_for_plan": 160.03,

"rows_for_plan": 99,

"pruned_by_cost": true

}

]

}

]

},

{

"attaching_conditions_to_tables": {

"original_condition": "((`test2`.`id` = `test1`.`id`) and (`test1`.`id` > 4999900))",

"attached_conditions_computation": [

],

"attached_conditions_summary": [

{

"table": "`test1`",

"attached": "(`test1`.`id` > 4999900)"

},

{

"table": "`test2`",

"attached": null

}

]

}

},

{

"refine_plan": [

{

"table": "`test1`",

"access_type": "range"

},

{

"table": "`test2`"

}

]

}

]

}

},

{

"join_execution": {

"select#": 1,

"steps": [

]

}

}

]

}

原文地址:https://www.cnblogs.com/katec/p/9239985.html

时间: 2024-11-12 12:03:40

用MySQL的optimizer_trace进行sql调优的相关文章

MySQL索引和SQL调优

MySQL索引 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree索引,因为这是平常使用MySQL时主要打交道的索引. MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. MySQL索引原理 索引目的 索引的目的在于提高查询效率,可以类比字典,如果要查“mysql”这个单词,

SQL调优

# 问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一.系统优化中一个很重要的方面就是SQL语句的优 化.对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个系统不是简单地能实现其功能就可,而是要写出高质量的 SQL语句,提高系统的可用性. 在多数情况下,Oracle

《高性能SQL调优精要与案例解析》一书谈主流关系库SQL调优(SQL TUNING或SQL优化)核心机制之——索引(index)

继<高性能SQL调优精要与案例解析>一书谈SQL调优(SQL TUNING或SQL优化),我们今天就谈谈各主流关系库中,占据SQL调优技术和工作半壁江山的.最重要的核心机制之一——索引(index).我们知道,<高性能SQL调优精要与案例解析>一书中也再三强调索引对SQL调优的重要性,可是上篇文章中也谈到,只看案例和解决问题的具体方法,而不掌握SQL调优的基础知识,是没有用的,我们必须做到知其然,更要知其所以然,才能做到融会贯通,活学活用,进而将SQL调优技术掌握到炉火纯青的地步.

SQL调优日志--内存问题

SQL调优日志--内存问题排查入门篇 概述 很多系统的性能问题,是由内存导致的.内存不够会导致页面频繁换入换出,IO队列高,进而影响数据库整体性能. 排查 内存对数据库性能非常重要.那么我当出现问题的时候,我们怎么排查性能问题呢? 存在问题 主要查看2个部分.页生命周期 Page Life Expectancy,和  lazy writer /sec. 页生命周期 的参考值在很久很久以前,很多同学可能看到过,建议值是300s.但是这是基于32位操作系统,最大只能使用4GB内存给出的. Jonat

Oracle SQL 调优健康检查脚本

Oracle SQL 调优健康检查脚本 我们关注数据库系统的性能,进行数据库调优的主要工作就是进行SQL的优化.良好的数据架构设计.配合应用系统中间件和写一手漂亮的SQL,是未来系统上线后不出现致命性能问题的有力保证. 在CBO时代,一个SQL的执行计划是多样的.影响执行计划的因素也从过去RBO时代的SQL书写规则变为综合性因素.这为我们生成更加优秀执行计划提供了基础,同时也给我们进行调优带来的很多麻烦. 目前我们通常的做法,是通过AWR报告或者调试手段,发现某某SQL有问题,之后从Librar

11g新特性-自动sql调优(Automatic SQL Tuning)

11g新特性-自动sql调优(Automatic SQL Tuning) 在Oracle 10g中,引进了自动sql调优特性.此外,ADDM也会监控捕获高负载的sql语句. 在Oracle 11g中,通过运行sql tuning advisor加强了自动sql调优功能.默认情况下是每天夜间通过自动任务的方式运行"自动sql调优". 自动sql调优的过程: 1.识别需要调优的sql语句  根据AWR中的CPU和I/O负载来识别 2.调优,生成新的sql profile 在维护窗口(mai

SQL调优常用方法

在使用DBMS时经常对系统的性能有非常高的要求:不能占用过多的系统内存和 CPU资源.要尽可能快的完成的数据库操作.要有尽可能高的系统吞吐量.如果系统开发出来不能满足要求的所有性能指标,则必须对系统进行调整,这个工作被称为调优.绝定DBMS的性能的因素有两个因素:硬件和软件.使用频率高的CPU.使用多处理器.加大内存容量.增加Cache.提高网络速度等这些都是非常有效的硬件调优方式,不过对硬件进行调优对系统性能的提高是有限的,如果有非常好的硬件条件但是如果编写的SQL质量非常差的话系统的性能并不

数据库学习——SQL调优

一.SQL调优与查询优化器 数据库性能调优一般从发现.分析和解决SQL语句执行中的问题着手,这个过程统称为SQL调优(SQL tuning). 1.了解查询优化器 例如,有些查询优化器对于连接操作,一般按连接对象在FROM子句中出现的先后次序进行连接.SQL程序设计者可以利用此特点将选择性高的小表放在前面,大表放在后面,以尽快淘汰无用的中间结果,从而节省查询处理开销.又如,有些查询优化器中,凡是查询条件用OR连接的,就一概不用索引,因而只能用全表扫描,可以考虑使用UNION ALL代替OR. 2

oracle sql调优集

************************************************************ 1.新建调优集对象 ************************************************************ ---授权 grant ADMINISTER ANY SQL TUNING SET to scott; ---删除存在的STS BEGIN DBMS_SQLTUNE.DROP_SQLSET( sqlset_name => 'OCPYAN