Innodb通过自动把主键列添加到每个二级索引来扩展它们:

CREATE TABLE t1 (
i1 INT NOT NULL DEFAULT 0,
i2 INT NOT NULL DEFAULT 0,
d DATE DEFAULT NULL,
PRIMARY KEY (i1, i2),
INDEX k_d (d)
) ENGINE = InnoDB;

该表定义(t1,t2)为联合主键,也定义个二级索引k_id 在列(d)上,但是内部innodb会扩展它,变成列index(d,i1,i2);

版本5.6.9之前,优化器不会这么优化,但在5.6.9,开始支持,可以得到更好的性能和更有效的执行计划;

优化器可以用扩展的二级索引来进行ref,range,index_merge等类型index access,松散的index sacns,join连接和排序优化,和min()/max()优化;

数据:

INSERT INTO t1 VALUES
(1, 1, '1998-01-01'), (1, 2, '1999-01-01'),
(1, 3, '2000-01-01'), (1, 4, '2001-01-01'),
(1, 5, '2002-01-01'), (2, 1, '1998-01-01'),
(2, 2, '1999-01-01'), (2, 3, '2000-01-01'),
(2, 4, '2001-01-01'), (2, 5, '2002-01-01'),
(3, 1, '1998-01-01'), (3, 2, '1999-01-01'),
(3, 3, '2000-01-01'), (3, 4, '2001-01-01'),
(3, 5, '2002-01-01'), (4, 1, '1998-01-01'),
(4, 2, '1999-01-01'), (4, 3, '2000-01-01'),
(4, 4, '2001-01-01'), (4, 5, '2002-01-01'),
(5, 1, '1998-01-01'), (5, 2, '1999-01-01'),
(5, 3, '2000-01-01'), (5, 4, '2001-01-01'),
(5, 5, '2002-01-01');

查询sql:

EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01';

这种情况下,优化器不会使用主键,因为主键有(t1,t2)组成,但是该查询中没有引用i2;优化器会选择二级索引 k_d(d) ,执行计划依赖与是否扩展index被使用;

当优化器没有使用index extensions时,他对待 k_d 仅仅为(d).

mysql> EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ref
possible_keys: PRIMARY,k_d
key: k_d
key_len: 4
ref: const
rows: 5
Extra: Using where; Using index

当优化器把index extensions考虑在内的话,对待k_d (d,i1,i2), 这种情况下,他可以使用最左前缀(d,i1)开得到一个更好的执行计划;

mysql> EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
type: ref
possible_keys: PRIMARY,k_d
key: k_d
key_len: 8
ref: const,const
rows: 1
Extra: Using index

两种情况下,key列显示优化器都会选择用二级索引k-d,但是 :

1:key_len列从4bytes 变成了8 bytes,说明了key 是查找的 列 d 和 i1,而不是仅仅d;

2: rows列计数从5减少到1,说明 innodb检测更少的行来得到结构;

3:Extra列从 using where;using index 变成了using index,意味着结果只使用了index,没有access数据行;

优化器使用扩展的Index行为不同也可以通过show status指令来观看:

FLUSH TABLE t1;
FLUSH STATUS;
SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = '2000-01-01';
SHOW STATUS LIKE 'handler_read%'

flush table :清除Table cache;

flush status:清除状态计数;

没有index extendsions,show status:

+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 5 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+

有index extensions,show status: handler_read_next 从5变成1

+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 1 |
| Handler_read_last | 0 |
| Handler_read_next | 1 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 0 |
+-----------------------+-------+
optimizer_switch系统变量的use_index_extensions标志可以控制是否优化器进行二级索引扩展,默认,是打开的,
SET optimizer_switch = 'use_index_extensions=off';
												

Mysql Index extends优化的更多相关文章

  1. 1229【MySQL】性能优化之 Index Condition Pushdown

    转自http://blog.itpub.net/22664653/viewspace-1210844/  [MySQL]性能优化之 Index Condition Pushdown2014-07-06 ...

  2. MYSQL数据库的优化

    我们究竟应该如何对MySQL数据库进行优化?下面我就从MySQL对硬件的选择.MySQL的安装.my.cnf的优化.MySQL如何进行架构设计及数据切分等方面来说明这个问题. 服务器物理硬件的优化 在 ...

  3. MySQL 调优/优化的 100 个建议

    MySQL 调优/优化的 100 个建议   MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供 101 条优化 MySQL 的建议.有些技巧适合特定 ...

  4. 理解MySQL——索引与优化

    转自:理解MySQL——索引与优化 写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存 ...

  5. MySQL Index详解

    FROM:http://blog.csdn.net/tianmo2010/article/details/7930482 ①MySQL Index 一.SHOW INDEX会返回以下字段 1.Tabl ...

  6. mysql使用索引优化查询效率

    索引的概念 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针.更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度.在没 ...

  7. [转]MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验

    本文转自:http://liangweilinux.blog.51cto.com/8340258/1728131 年,嘿,废话不多说,下面开启MySQL优化之旅! 我们究竟应该如何对MySQL数据库进 ...

  8. MYSQL查询语句优化

    mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬件优化,应用层面优化(web服务器,缓存)等等.这里的记录的优化技巧更适用于开发人员,都是从网络上收集和自己整 ...

  9. mysql数据库性能优化(包括SQL,表结构,索引,缓存)

    优化目标减少 IO 次数IO永远是数据库最容易瓶颈的地方,这是由数据库的职责所决定的,大部分数据库操作中超过90%的时间都是 IO 操作所占用的,减少 IO 次数是 SQL 优化中需要第一优先考虑,当 ...

随机推荐

  1. CSS3 banner图片的标签效果

    放body看,你懂的:)

  2. [C#]如何访问及调用类中私有成员及方法

    本文为原创文章.源代码为原创代码,如转载/复制,请在网页/代码处明显位置标明原文名称.作者及网址,谢谢! 开发工具:VS2017 语言:C# DotNet版本:.Net FrameWork 4.0及以 ...

  3. 自动刷新 CSS文件

    自动刷新 CSS文件 使用任何代码工具码 CSS,都是需要保存后再切换到浏览器按 F5 刷新查看效果,一次又一次,不管这个改动仅是一个小小的颜色.使用 CSSrefresh 后,改动 CSS 文件保存 ...

  4. Java学习笔记19(String类)

    String代表字符串,在Java中,所有的字符串字面值都作为此类的实例实现 字符串的特点以及简单的原理分析: package demo; /* * String类的特点: * 所有的"&q ...

  5. 【二分图】P3386洛谷模板

    题目背景 二分图 题目描述 给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数 输入输出格式 输入格式: 第一行,n,m,e 第二至e+1行,每行两个正整数u,v,表示u,v有一条连边 ...

  6. DAY2-java对你有点好感2018-1-10

    第二天,对你有好感,还是不想复习,继续学习!! 第一天:归在日记分类,不能改为随笔,无奈/ 链接http://www.cnblogs.com/archer-lcy/diary/2018/01/09/8 ...

  7. 如何删除chrome地址栏里面曾经输错的地址

    在chrome浏览器的地址栏输入你想删除的网址的部分字幕,比如,在地址栏输入form,然后用键盘上的方向键定位到你想删除的那个错误的地址,如下图所示   然后在键盘上按 shift+del 组合键将其 ...

  8. ResourceBundleViewResolver

    1 springmvc中ResourceBundleViewResolver解析器的使用1.1 springmvc.xml的配置因为我配置了多个解析器,所以额外的加了order属性,value值越低, ...

  9. 【转载】从头编写 asp.net core 2.0 web api 基础框架 (2)

    Github源码地址是: https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scra ...

  10. [PHP] PHP与Apache的模块配合说明

    1.当PHP需要在Apache服务器下运行时 一般来说,它可以mod_php5模块的形式集成, 此时mod_php5模块的作用是接收Apache传递过来的PHP文件请求,并处理这些请求, 然后将处理后 ...