(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 优化器的更多相关文章

  1. 0104探究MySQL优化器对索引和JOIN顺序的选择

    转自http://www.jb51.net/article/67007.htm,感谢博主 本文通过一个案例来看看MySQL优化器如何选择索引和JOIN顺序.表结构和数据准备参考本文最后部分" ...

  2. 机智的MySQL优化器 --- is null

    [介绍] 工作的越久越到的的问题越多,就越是觉得一些“老话”历久弥新:由于最近的学习计划是深入的学习一遍MySQL优化器:学习过程中的一些成果 也会发布到这里,一来是为了整理自己已经知道的和新学到的, ...

  3. 数据库 mysql 优化器原理

    MySQL查询优化器有几个目标,但是其中最主要的目标是尽可能地使用索引,并且使用最严格的索引来消除尽可能多的数据行. 你的最终目标是提交SELECT语句查找数据行,而不是排除数据行.优化器试图排除数据 ...

  4. MySQL优化器cost计算

    记录MySQL 5.5上,优化器进行cost计算的方法. 第一篇: 单表的cost计算 数据结构: 1. table_share: 包含了表的元数据,其中索引部分: key_info:一个key的结构 ...

  5. MySQL优化器 --- index_merge

    [背景] 对于关系数据库中的一张表,通常来说数据页面的总大小要比较某一个索引占用的页面要大的多(上面说的索引是不包涵主键索引的); 更进一步我们可以推导出,如果我们通过读索引就能解决问题,那么它相比读 ...

  6. MySQL优化器功能开关optimizer_switch

    MySQL 8.0新增特性 use_invisible_indexes:是否使用不可见索引,MySQL 8.0新增可以创建invisible索引,这一开关控制优化器是否使用invisible索引,on ...

  7. 《Mysql - 优化器是如何选择索引的?》

    一:概念 - 在 索引建立之后,一条语句可能会命中多个索引,这时,索引的选择,就会交由 优化器 来选择合适的索引. - 优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句. 二: ...

  8. 如何干涉MySQL优化器使用hash join

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 前言 实验 总结 前言 数据库的优化器相当于人类的大 ...

  9. MySQL优化器不使用索引的情况

    优化器选择不适用索引的情况 有时候,有乎其并没有选择索引而去查找数据,而是通过扫描聚集索引,也就是直接进行全表的扫描来得到数据.这种情况多发生于范围查找.JOIN链接操作等情况.例如 ; 通过SHOW ...

  10. MySQL优化器join顺序

    前一篇介绍了cost的计算方法,下面测试一下两表关联的查询: 测试用例 CREATE TABLE `xpchild` ( `id` int(11) NOT NULL, `name` varchar(1 ...

随机推荐

  1. Python 文本相似度分析

    环境 Anaconda3 Python 3.6, Window 64bit 目的 利用 jieba 进行分词,关键词提取 利用gensim下面的corpora,models,similarities ...

  2. 20165332《Java程序设计》第2周学习总结

    <Java程序设计>第2周学习总结 2-3章学习内容 第二章 标识符(名字) 关键字 int class 基本数据类型 逻辑类型 整数类型 字符类型 浮点类型 各类型相互转换 --低级别给 ...

  3. 牛客练习赛13D

    定义一个数字为幸运数字当且仅当它的所有数位都是4或者7.比如说,47.744.4都是幸运数字而5.17.467都不是.现在想知道在1...n的第k小的排列(permutation,https://en ...

  4. 七 web爬虫讲解2—urllib库爬虫—状态吗—异常处理—浏览器伪装技术、设置用户代理

    如果爬虫没有异常处理,那么爬行中一旦出现错误,程序将崩溃停止工作,有异常处理即使出现错误也能继续执行下去 1.常见状态吗 301:重定向到新的URL,永久性302:重定向到临时URL,非永久性304: ...

  5. RedHat Linux服务器安全配置细节

    1.概述 Linux服务器版本:RedHat Linux AS 2.1 对于开放式的操作系统---Linux,系统的安全设定包括系统服务最小化.限制远程存取.隐藏重要资料.修补安全漏洞.采用安全工具以 ...

  6. 【html】html笔记综合

    基本标签与属性 <html>全部 <body>主体 <h1>标题 <p>段落 <br>空行,一般都会额外添加,并不总是需要自己添加,可以在& ...

  7. 浅析Java基本数据类型

    作为一种强类型语言,Java针对每一种数据都定义了明确的数据类型.大体来讲可分为:基本数据类型和引用数据类型:在此,主要讨论前者,后者以后再继续探究. Java基本数据类型分为四类八种: 1: 整数 ...

  8. Azure Sql Database为某个数据库创建单独的访问账户

    由于SQL Management Studio对Azure SQL Database支持不完美,不能使用图形界面,因此配置数据库就会有不同的麻烦,下面是本人配置访问账户的一些经验: 1.以管理员登陆之 ...

  9. [分享]Google 全球 IP 地址库[Google Global Cache IPs]

    Google 全球 IP 地址库 IP 地址来源:http://www.kookle.co.nr,共计4351个. Bulgaria 93.123.23.1 93.123.23.2 93.123.23 ...

  10. kali视频学习(11-15)

    第四周kali视频(11-15)学习 11.漏洞分析之OpenVAS使用 12.漏洞分析之扫描工具 13.漏洞分析之WEB爬行 14.漏洞分析之WEB漏洞扫描(一) 15.漏洞分析之WEB漏洞扫描(二 ...