在我们调优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": [
]
}
}
]
}
- 【叶问】 MySQL常用的sql调优手段或工具有哪些
MySQL常用的sql调优手段或工具有哪些1.根据执行计划优化 通常使用desc或explain,另外可以添加format=json来输出更详细的json格式的执行计划,主要注意点如下: ...
- 你们一般都是怎么进行SQL调优的?MySQL在执行时是如何选择索引的?
前言 过年回来的第二周了,终于有时间继续总结知识了.这次来看一下SQL调优的知识,这类问题基本上面试的时候都会被问到,无论你的岗位是后端,运维,测试等等. 像本文标题中的两个问题,就是我在实际面试过程 ...
- MySQL索引和SQL调优手册
MySQL索引 MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree索引,哈希索引,全文索引等等.为了避免混乱,本文将只关注于BTree ...
- SQL调优
# 问题的提出 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,但是如果将应用 系统提交实际应用后,随着数据库中数据的增加,系 ...
- Oracle中SQL调优(SQL TUNING)之最权威获取SQL执行计划大全
该文档为根据相关资料整理.总结而成,主要讲解Oracle数据库中,获取SQL语句执行计划的最权威.最正确的方法.步骤,此外,还详细说明了每种方法中可选项的意义及使用方法,以方便大家和自己日常工作中查阅 ...
- 《高性能SQL调优精要与案例解析》一书谈主流关系库SQL调优(SQL TUNING或SQL优化)核心机制之——索引(index)
继<高性能SQL调优精要与案例解析>一书谈SQL调优(SQL TUNING或SQL优化),我们今天就谈谈各主流关系库中,占据SQL调优技术和工作半壁江山的.最重要的核心机制之一——索引(i ...
- SQL调优常用方法
在使用DBMS时经常对系统的性能有非常高的要求:不能占用过多的系统内存和 CPU资源.要尽可能快的完成的数据库操作.要有尽可能高的系统吞吐量.如果系统开发出来不能满足要求的所有性能指标,则必须对系统进 ...
- 读《程序员的SQL金典》[4]--SQL调优
一.SQL注入 如果程序中采用sql拼接的方式书写代码,那么很可能存在SQL注入漏洞.避免的方式有两种: 1. 对于用户输入过滤敏感字母: 2. 参数化SQL(推荐). 二.索引 ①索引分类 聚簇索引 ...
- [SQL SERVER系列]读书笔记之SQL注入漏洞和SQL调优
最近读了程序员的SQL金典这本书,觉得里面的SQL注入漏洞和SQL调优总结得不错,下面简单讨论下SQL注入漏洞和SQL调优. 1. SQL注入漏洞 由于“'1'='1'”这个表达式永远返回 true, ...
随机推荐
- 服务间调用--feign跟ribbon
微服务一般来说当然是多服务多实例的,那么这些服务之间如何相互调用呢?spring cloud之前我们用dubbo,把服务开放出来,在xml配好后就可以像调用本地service一样调用其它模块的服务了: ...
- C++ stl vector介绍
转自: STL vector用法介绍 介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作.本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if ...
- .NET Core 部署到CentOS–3.supervisord守护进
1. 安装 sudo yum install python-setuptoolssudo easy_install supervisor 2. 配置 安装成功后,输入supervisord 会显示配置 ...
- 二维码项目实例为二维码添加logo
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- spring mvc改造成spring boot
一.新增依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- dojo事件绑定
Dojo如何动态绑定事件的小demo <html> <title>事件绑定测试test</title> <head></head> < ...
- Android TextView之空格占位法
在Android布局中进行使用到空格,为了实现文字的对齐.具体要怎么使用了? •请忽视文中‘& #160’中&和#之间的空格 空格: & #160; 窄空格: & #8 ...
- Android Vmp加固实现流程图
0x00: 目前各种加固都说是VMP了,简单分析市面上的加固,然后自己实现了一个类似原理的加固,大致流程图如下: 加固端: 解释器:
- [原创]在Debian9上配置NAS
序言 此教程安装的都是最新版本的.由于是当NAS让它非常稳定的运行,所以能不安装的软件尽量不要安装. 一.准备工作 1. 更新系统 没啥,就他喵想用个最新的. apt update && ...
- maven下nutz与servlet报错org.nutz.mvc.NutFilter cannot be cast to javax.servlet.Filter
使用maven搭建nutz时,加入servlet报错:org.nutz.mvc.NutFilter cannot be cast to javax.servlet.Filter 十二月 03, 201 ...