跟踪MYSQL 的查询优化过程方法
http://dev.mysql.com/doc/internals/en/tracing-example.html
http://blog.chinaunix.net/uid-20785090-id-5597524.html
handle_select()
mysql_select()
JOIN::prepare()
setup_fields()
JOIN::optimize() /* optimizer is from here ... */
optimize_cond()
opt_sum_query()
make_join_statistics()
get_quick_record_count()
choose_plan()
/* Find the best way to access tables */
/* as specified by the user. */
optimize_straight_join()
best_access_path()
/* Find a (sub-)optimal plan among all or subset */
/* of all possible query plans where the user */
/* controls the exhaustiveness of the search. */
greedy_search()
best_extension_by_limited_search()
best_access_path()
/* Perform an exhaustive search for an optimal plan */
find_best()
make_join_select() /* ... to here */
JOIN::exec()
CREATE TABLE `t` (
`a` int() NOT NULL,
`b` int() DEFAULT NULL,
`c` int() NOT NULL,
PRIMARY KEY (`a`),
KEY `b` (`b`),
KEY `ix` (`b`,`c`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
json格式: mysql> explain format=json select b from t\G
*************************** . row **********************
EXPLAIN: {
"query_block": {
"select_id": ,
"cost_info": {
"query_cost": "1.20"
},
"table": {
"table_name": "t",
"access_type": "index",
"key": "b",
"used_key_parts": [
"b"
],
"key_length": "",
"rows_examined_per_scan": ,
"rows_produced_per_join": ,
"filtered": "100.00",
"using_index": true,
"cost_info": {
"read_cost": "1.00",
"eval_cost": "0.20",
"prefix_cost": "1.20",
"data_read_per_join": ""
},
"used_columns": [
"b"
]
}
}
}
row in set, warning (0.00 sec)
更加详细的过程生成: 1.set optimizer_trace_max_mem_size=300000;
2.set end_markers_in_json=true;
3.set optimizer_trace="enabled=on"; 4.sql语句 5.select trace from information_schema.optimizer_trace\G;
6.set optimizer_trace="enabled=off";
主要分为三个部分
下面详细介绍join_optimization的过程:
1)condition_processing阶段,进行where条件处理,分别是相等处理,常量处理,删除冗余条件
2)ref_optimizer_key_uses阶段,查找可进行ref type访问的索引(索引的等值访问)。
3)records_estimation阶段,进行访问开销预估。这个阶段是最复杂的。先处理访问类型(explain select_type字段的值),候选项分别为全表扫描和所有的索引,开销最小的那个胜出。如果你的语句有Group By,那么在group_index_range子阶段确定是否有适用于range 访问的索引。
4)considered_execution_plans节显示了选定的执行计划
5)attaching_conditions_to_tables分析where条件是否可以执行pushdown,应该是再扫描该表时过滤掉。
6)clause_processing阶段分别处理group by, order by从句。
eg:
set optimizer_trace_max_mem_size=300000;
set end_markers_in_json=true;
set optimizer_trace="enabled=on";
mysql> select b from t;
mysql> select trace from information_schema.optimizer_trace\G
*************************** . row ***************************
trace: {
"steps": [
{
"join_preparation": {
"select#": ,
"steps": [
{
"expanded_query": "/* select#1 */ select `t`.`b` AS `b` from `t`"
}
]
}
},
{
"join_optimization": {
"select#": ,
"steps": [
{
"table_dependencies": [
{
"table": "`t`",
"row_may_be_null": false,
"map_bit": ,
"depends_on_map_bits": [
]
}
]
},
{
"rows_estimation": [
{
"table": "`t`",
"table_scan": {
"rows": ,
"cost":
}
}
]
},
{
"considered_execution_plans": [
{
"plan_prefix": [
],
"table": "`t`",
"best_access_path": {
"considered_access_paths": [
{
"rows_to_scan": ,
"access_type": "scan",
"resulting_rows": ,
"cost": 1.2,
"chosen": true
}
]
},
"condition_filtering_pct": ,
"rows_for_plan": ,
"cost_for_plan": 1.2,
"chosen": true
}
]
},
{
"attaching_conditions_to_tables": {
"original_condition": null,
"attached_conditions_computation": [
],
"attached_conditions_summary": [
{
"table": "`t`",
"attached": null
}
]
}
},
{
"refine_plan": [
{
"table": "`t`"
}
]
}
]
}
},
{
"join_explain": {
"select#": ,
"steps": [
]
}
}
]
}
row in set (0.00 sec)
set optimizer_trace="enabled=off";
select trace into dumpfile "json.txt" from information_schema.optimizer_trace;
跟踪MYSQL 的查询优化过程方法的更多相关文章
- 4种MySQL分页查询优化的方法,你知道几个?
前言 当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的 ...
- Mysql单表访问方法,索引合并,多表连接原理,基于规则的优化,子查询优化
参考书籍<mysql是怎样运行的> 非常推荐这本书,通俗易懂,但是没有讲mysql主从等内容 书中还讲解了本文没有提到的子查询优化内容, 本文只总结了常见的子查询是如何优化的 系列文章目录 ...
- MySQL 的查询优化
说起 MySQL 的查询优化,相信大家收藏了一堆奇技淫巧:不能使用 SELECT *.不使用 NULL 字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解它背 ...
- WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)
WebAPI调用笔记 前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...
- MySQL 慢查询优化
为什么查询速度会慢 1.慢是指一个查询的响应时间长.一个查询的过程: 客户端发送一条查询给服务器 服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果.否则进入下一个阶段 服务器端进行 ...
- MySQL锁表解决方法
https://blog.csdn.net/a5582ddff/article/details/79566678 MySQL锁表解决方法 一.我的处理过程 1.查进程,主要是查找被锁表的那个进程的ID ...
- mysql数据库查询过程探究和优化建议
查询过程探究 我们先看一下向mysql发送一个查询请求时,mysql做了什么? 如上图所示,查询执行的过程大概可分为6个步骤: 客户端向MySQL服务器发送一条查询请求 服务器首先检查查询缓存,如果命 ...
- 《MySQL慢查询优化》之SQL语句及索引优化
1.慢查询优化方式 服务器硬件升级优化 Mysql服务器软件优化 数据库表结构优化 SQL语句及索引优化 本文重点关注于SQL语句及索引优化,关于其他优化方式以及索引原理等,请关注本人<MySQ ...
- Mysql导入数据库的方法
mysql导入数据库的方法 | 浏览:41023 | 更新:2012-11-01 19:45 1 2 3 4 5 6 7 分步阅读 MySQL是一个中.小型关系型数据库管理系统,由瑞典MySQL AB ...
随机推荐
- thinkphp使用问题
下面总结一些,我在使用中遇到的问题,以后遇到了再补充 一.<a>标签的跳转问题 问题:我在控制器Home/Index/index里面使用了Public里面的index.html模板,ind ...
- WPF后台访问XAML元素
当我们需要从后台访问xaml文件时,我们可以通过这样的方式来操作: private void button1_Click(object sender, RoutedEventArgs e) { Sys ...
- ruby 中文支持设置
学习Ruby的过程中,对于于涉及中文的的代码的时候,需要添加如下代码在首行 # encoding: utf-8 或者EMAC写法 # -*- coding : utf-8 -*- 因为Ruby编译器会 ...
- 学习Swift -- 析构过程
析构过程 析构器只适用于类类型,当一个类的实例被释放之前,析构器会被立即调用.析构器用关键字deinit来标示,类似于构造器要用init来标示. 原理 Swift 会自动释放不再需要的实例以释放资源, ...
- 利用servlet做转发,实现js跨域解决同源问题
做前端开发,避免不了跨域这个问题,跨域具体什么概念,不赘述,博客里太多.简单说下,我们用js发请求,不管post还是get,如果发请求的对象和当前web页面不在同一域名下,浏览器的同源策略会限制发请求 ...
- hibernate中的缓存机制
一.为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数据源中的数 ...
- 15个你不知道的杀手级Google Chrome功能
之前写过一篇我为什么使用Google Chrome浏览器,算是在使用了一段时间的Google Chrome后的一点粗浅认识,最近读到一篇文章15 Killer Google Chrome Featur ...
- C语言的static和extern关键字
我的博客:www.while0.com 如果A.c要包含B.c里的一个变量或函数,则在A.c中要用extern关键字声明.注意: ①如果是包含的B.c里的函数,则在A.c里声明的时候可以不写exter ...
- bzoj1260
很容易脑补出来的区间dp O(n3)的 var f:array[0..51,0..51] of longint; i,n,j,l,k:longint; s:string; function ...
- PuTTY 'modmul()' 函数缓冲区下溢漏洞(CVE-2013-4206)
漏洞版本: PuTTY 0.52 - 0.63 漏洞描述: BUGTRAQ ID: 61645 CVE(CAN) ID: CVE-2013-4206 PuTTY是Windows和Unix平台上的PuT ...