MySQL 优化器
(system@127.0.0.1:3306) [trunk]> show variables like '%performance_sch%';
+----------------------------------------------------------+-------+
| Variable_name                                            | Value |
+----------------------------------------------------------+-------+
| performance_schema                                       | ON    |
########################################
实验操作脚本:
CREATE TABLE `t1` (
`c1` int(11) NOT NULL DEFAULT '',
`c2` varchar(128) DEFAULT NULL,
`c3` varchar(64) DEFAULT NULL,
`c4` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`),
KEY `ind_c2` (`c2`),
KEY `ind_c4` (`c4`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; insert into t1 values(1,'a','A',10);
insert into t1 values(2,'b','B',20);
insert into t1 values(3,'b','BB',20);
insert into t1 values(4,'b','BBB',30);
insert into t1 values(5,'b','BBB',40);
insert into t1 values(6,'c','C',50);
insert into t1 values(7,'d','D',60);
mysql> select * from t1;
+----+------+------+------+
| c1 | c2 | c3 | c4 |
+----+------+------+------+
| 1 | a | A | 10 |
| 2 | b | B | 20 |
| 3 | b | BB | 20 |
| 4 | b | BBB | 30 |
| 5 | b | BBB | 40 |
| 6 | c | C | 50 |
| 7 | d | D | 60 |
+----+------+------+------+ set optimizer_trace="enabled=on";
select * from information_schema.optimizer_trace\G
SET optimizer_trace="enabled=off";
#################################################
1、执行以下SQL为什么不走索引ind_c2?
explain select * from t1 where  c4=20 and c2='b';
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2,ind_c4 | ind_c4 | 5       | const |    2 |    57.14 | Using where |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
--c4=40的过滤性比c2好很多
--filtered=57.14
---
"analyzing_roworder_intersect": {
                      "intersecting_indexes": [
                        {
                          "index": "ind_c4",
                          "index_scan_cost": 1.0011,
                          "cumulated_index_scan_cost": 1.0011,
                          "disk_sweep_cost": 1.75,
                          "cumulated_total_cost": 2.7511,
                          "usable": true,
                          "matching_rows_now": 2,
                          "isect_covering_with_this_index": false,
                          "chosen": true
                        },
                        {
                          "index": "ind_c2",
                          "index_scan_cost": 1.1429,
                          "cumulated_index_scan_cost": 2.144,
                          "disk_sweep_cost": 1,
                          "cumulated_total_cost": 3.144,
                          "usable": true,
                          "matching_rows_now": 1.3333,
                          "isect_covering_with_this_index": false,
                          "chosen": false,
                          "cause": "does_not_reduce_cost"
                        }
(system@127.0.0.1:3306) [test]> explain select * from t1 force index(ind_c2) where  c4=20 and c2='b';
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2        | ind_c2 | 387     | const |    4 |    20.00 | Using where |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
--key_len,rowd,filtered
2、where条件中字段c2和c4换个位置,索引还是不走ind_c2?为什么?
explain select * from t1 where  c2='b' and c4=20;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2,ind_c4 | ind_c4 | 5       | const |    2 |    66.67 | Using where |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
--走index跟字段的顺序位置无关
--filtered=66.67
"analyzing_roworder_intersect": {
                      "intersecting_indexes": [
                        {
                          "index": "ind_c4",
                          "index_scan_cost": 1.0011,
                          "cumulated_index_scan_cost": 1.0011,
                          "disk_sweep_cost": 1.75,
                          "cumulated_total_cost": 2.7511,
                          "usable": true,
                          "matching_rows_now": 2,
                          "isect_covering_with_this_index": false,
                          "chosen": true
                        },
                        {
                          "index": "ind_c2",
                          "index_scan_cost": 1.1429,
                          "cumulated_index_scan_cost": 2.144,
                          "disk_sweep_cost": 1,
                          "cumulated_total_cost": 3.144,
                          "usable": true,
                          "matching_rows_now": 1.3333,
                          "isect_covering_with_this_index": false,
                          "chosen": false,
                          "cause": "does_not_reduce_cost"
                        }
3、如下语句,换个条件c2=\'c\',为什么可以走索引ind_c2?
explain select * from t1 where  c2='c' and c4=20;
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key    | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+--------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2,ind_c4 | ind_c2 | 387     | const |    1 |    33.33 | Using where |
--filtered=33.33,c2=c的选择性比c4=20要好
"analyzing_roworder_intersect": {
                      "intersecting_indexes": [
                        {
                          "index": "ind_c2",
                          "index_scan_cost": 1,
                          "cumulated_index_scan_cost": 1,
                          "disk_sweep_cost": 1,
                          "cumulated_total_cost": 2,
                          "usable": true,
                          "matching_rows_now": 1,
                          "isect_covering_with_this_index": false,
                          "chosen": true
                        },
                        {
                          "index": "ind_c4",
                          "index_scan_cost": 1.0011,
                          "cumulated_index_scan_cost": 2.0011,
                          "disk_sweep_cost": 0,
                          "cumulated_total_cost": 2.0011,
                          "usable": true,
                          "matching_rows_now": 0.3333,
                          "isect_covering_with_this_index": false,
                          "chosen": false,
                          "cause": "does_not_reduce_cost"
                        }
4、创建复合索引
ALTER TABLE t1 ADD KEY ind_c2_c4(`c2`,`c4`);
1)为什么不走复合索引ind_c2_c4?
explain select * from t1 where  c2='b' and c4=20;
+----+-------------+-------+------------+------+-------------------------+--------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys           | key    | key_len | ref   | rows | filtered | Extra       |
+----+-------------+-------+------------+------+-------------------------+--------+---------+-------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2,ind_c4,ind_c2_c4 | ind_c4 | 5       | const |    2 |    66.67 | Using where |
"analyzing_range_alternatives": {
                    "range_scan_alternatives": [
                      {
                        "index": "ind_c2",
                        "ranges": [
                          "b <= c2 <= b"
                        ],
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 4,
                        "cost": 5.81,
                        "chosen": false,
                        "cause": "cost"
                      },
                      {
                        "index": "ind_c4",
                        "ranges": [
                          "20 <= c4 <= 20"
                        ],
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,
                        "chosen": true
                      },
                      {
                        "index": "ind_c2_c4",
                        "ranges": [
                          "b <= c2 <= b AND 20 <= c4 <= 20"
                        ],
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "rows": 2,
                        "cost": 3.41,
                        "chosen": false,
                        "cause": "cost"
                      }
                    ],
"analyzing_roworder_intersect": {
                      "intersecting_indexes": [
                        {
                          "index": "ind_c2_c4",
                          "index_scan_cost": 1.0476,
                          "cumulated_index_scan_cost": 1.0476,
                          "disk_sweep_cost": 1.75,
                          "cumulated_total_cost": 2.7976,
                          "usable": true,
                          "matching_rows_now": 2,
                          "isect_covering_with_this_index": false,
                          "chosen": true
                        },
                        {
                          "index": "ind_c4",
                          "cumulated_total_cost": 2.7976,
                          "usable": false,
                          "cause": "does_not_reduce_cost_of_intersect"
                        },
                        {
                          "index": "ind_c2",
                          "cumulated_total_cost": 2.7976,
                          "usable": false,
                          "cause": "does_not_reduce_cost_of_intersect"
                        }
                  "chosen_range_access_summary": {
                    "range_access_plan": {
                      "type": "range_scan",
                      "index": "ind_c4",
                      "rows": 2,
                      "ranges": [
                        "20 <= c4 <= 20"
                      ]
                    },
                    "rows_for_plan": 2,
                    "cost_for_plan": 3.41,
                    "chosen": true
2)为什么又可以走复合索引ind_c2_c4??
explain select c2,c4 from t1 where  c2='b' and c4=20;
+----+-------------+-------+------------+------+-------------------------+-----------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys           | key       | key_len | ref         | rows | filtered | Extra       |
+----+-------------+-------+------------+------+-------------------------+-----------+---------+-------------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ref  | ind_c2,ind_c4,ind_c2_c4 | ind_c2_c4 | 392     | const,const |    2 |   100.00 | Using index |
+----+-------------+-------+------------+------+-------------------------+-----------+---------+-------------+------+----------+-------------+
"analyzing_roworder_intersect": {
                      "intersecting_indexes": [
                        {
                          "index": "ind_c2_c4",
                          "index_scan_cost": 1.0476,
                          "cumulated_index_scan_cost": 1.0476,
                          "disk_sweep_cost": 0,
                          "cumulated_total_cost": 1.0476,
                          "usable": true,
                          "matching_rows_now": 2,
                          "isect_covering_with_this_index": true,
                          "chosen": true
                        }
                      ],
                      "clustered_pk": {
                        "clustered_pk_added_to_intersect": false,
                        "cause": "no_clustered_pk_index"
                      },
                      "chosen": false,
                      "cause": "too_
------
(system@127.0.0.1:3306) [test]> show variables like '%sample%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| innodb_stats_persistent_sample_pages | 20    |--持久化
| innodb_stats_sample_pages            | 8     |--32(xx)
| innodb_stats_transient_sample_pages  | 8     |--32
(system@127.0.0.1:3306) [test]> show variables like '%persi%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| innodb_stats_persistent              | ON    |
| innodb_stats_persistent_sample_pages | 20    |
(system@127.0.0.1:3306) [test]> show variables like 'innodb_stats_on_metadata';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_stats_on_metadata | OFF   |
SHOW TABLE STATUS、 SHOW INDEX
ANALYZE TABLE
MySQL 优化器的更多相关文章
- 0104探究MySQL优化器对索引和JOIN顺序的选择
		
转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...
 - 机智的MySQL优化器 --- is null
		
[介绍] 工作的越久越到的的问题越多,就越是觉得一些“老话”历久弥新:由于最近的学习计划是深入的学习一遍MySQL优化器:学习过程中的一些成果 也会发布到这里,一来是为了整理自己已经知道的和新学到的, ...
 - 数据库 mysql 优化器原理
		
MySQL查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行. 你的最终目标是提交SELECT语句查找数据行,而不是排除数据行.优化器试图排除数据 ...
 - MySQL优化器cost计算
		
记录MySQL 5.5上,优化器进行cost计算的方法. 第一篇: 单表的cost计算 数据结构: 1. table_share: 包含了表的元数据,其中索引部分: key_info:一个key的结构 ...
 - MySQL优化器 --- index_merge
		
[背景] 对于关系数据库中的一张表,通常来说数据页面的总大小要比较某一个索引占用的页面要大的多(上面说的索引是不包涵主键索引的); 更进一步我们可以推导出,如果我们通过读索引就能解决问题,那么它相比读 ...
 - MySQL优化器功能开关optimizer_switch
		
MySQL 8.0新增特性 use_invisible_indexes:是否使用不可见索引,MySQL 8.0新增可以创建invisible索引,这一开关控制优化器是否使用invisible索引,on ...
 - 《Mysql - 优化器是如何选择索引的?》
		
一:概念 - 在 索引建立之后,一条语句可能会命中多个索引,这时,索引的选择,就会交由 优化器 来选择合适的索引. - 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句. 二: ...
 - 如何干涉MySQL优化器使用hash join
		
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 实验 总结 前言 数据库的优化器相当于人类的大 ...
 - MySQL优化器不使用索引的情况
		
优化器选择不适用索引的情况 有时候,有乎其并没有选择索引而去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据.这种情况多发生于范围查找.JOIN链接操作等情况.例如 ; 通过SHOW ...
 - MySQL优化器join顺序
		
前一篇介绍了cost的计算方法,下面测试一下两表关联的查询: 测试用例 CREATE TABLE `xpchild` ( `id` int(11) NOT NULL, `name` varchar(1 ...
 
随机推荐
- spring: spittr实例 构建简单的web应用 Test测试用例
			
本例为Test,测试上一贴的程序 package spittr.web; import org.junit.Test; import org.springframework.test.web.serv ...
 - Caffe初试
			
1.基本概念 Caffe是一个比较流行的神经网络框架,它支持C++.Python等语言,容易上手,但是代码貌似不怎么好读,等有空我...;) 2.Windows10下的部署 我把我Windows下的编 ...
 - 【python】使用asyncore进行异步通信
			
参考博文:http://blog.csdn.net/livefun/article/details/8721772 参考博文:https://www.cnblogs.com/tomato0906/ar ...
 - Chrome字体变粗
			
如图.解决方案,看看CSS中用了什么字体,卸载某个字体. 因为我装了一个新的字体,CSS中有这个字体的网页都会变粗.删掉这个字体就恢复正常了
 - eclipse mars4.5安装hibernate开发环境
			
在安装hibernate插件过程中遇到下面前三张图片所示的现象是没关系的,只要最后能看到第四张图的结果就说明安装成功,我一开始不知道走了好多弯路.我用的eclipse mars4.5,采用了在线安装的 ...
 - Java并发编程总结
			
基础概念 1.什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)?原子操作(atomic operation)意为"不可被中断的一个或一 ...
 - HTTP返回结果状态码小结
			
HTTP 状态码负责表示客户端 HTTP 请求的返回结果.标记服务器端的处理是否正常.通知出现的错误等工作. 一.状态码的类别 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果.借助状态 ...
 - Photoshop脚本指南——Hello World
			
作为一个程序猿,每一个东西的学习都是从Hello World开始的,从今天开始,让我们一起进入Photoshop脚本的世界,并以Hello World开始我们的旅程. 1.简介 Photoshop支持 ...
 - Android 进阶8:进程通信之 Binder 机制浅析
			
读完本文你将了解: IBinder Binder Binder 通信机制 Binder 驱动 Service Manager Binder 机制跨进程通信流程 Binder 机制的优点 总结 Than ...
 - transition 总结
			
详情:http://www.css88.com/book/css/properties/transition/transition-property.htm left不能进行transition