MySQL联合索引最左匹配范例
MySQL联合索引最左匹配范例
参考文章:http://blog.jobbole.com/24006/ 创建示例表。
示例表来自MySQL官方文档: https://dev.mysql.com/doc/employee/en/
CREATE TABLE titles (
emp_no INT NOT NULL,
title VARCHAR(50) NOT NULL,
from_date DATE NOT NULL,
to_date DATE,
PRIMARY KEY (emp_no,title,from_date)
) ; 导入测试数据 load_titles.dump
https://github.com/datacharmer/test_db 索引情况
mysql> show index from titles;
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+------
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comme
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+------
| titles | 0 | PRIMARY | 1 | emp_no | A | 0 | NULL | NULL | | BTREE |
| titles | 0 | PRIMARY | 2 | title | A | 0 | NULL | NULL | | BTREE |
| titles | 0 | PRIMARY | 3 | from_date | A | 0 | NULL | NULL | | BTREE |
+--------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+------
3 rows in set (0.00 sec) 情况一.WHERE条件中全部列都在索引中
不管WHERE的顺序如何执行计划都可以完整用到索引。
mysql> desc SELECT * FROM titles WHERE emp_no='' AND title='Senior Engineer' AND from_date='1986-06-26';
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| 1 | SIMPLE | titles | NULL | const | PRIMARY | PRIMARY | 159 | const,const,const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE title='Senior Engineer' AND emp_no='' AND from_date='1986-06-26';
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| 1 | SIMPLE | titles | NULL | const | PRIMARY | PRIMARY | 159 | const,const,const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.01 sec) mysql> desc SELECT * FROM titles WHERE from_date='1986-06-26' AND title='Senior Engineer' AND emp_no='';
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| 1 | SIMPLE | titles | NULL | const | PRIMARY | PRIMARY | 159 | const,const,const | 1 | 100.00 | NULL |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' AND title in('Senior Engineer','Staff','Assistant Engineer') AND from_date='1986-06-26';
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | range | PRIMARY | PRIMARY | 159 | NULL | 3 | 100.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no in('','','','') AND title in('Senior Engineer','Staff','Assistant Engineer') AND from_date='1986-06-26';
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | range | PRIMARY | PRIMARY | 159 | NULL | 12 | 100.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' AND title='Senior Engineer' AND from_date>='1986-06-26';
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | range | PRIMARY | PRIMARY | 159 | NULL | 1 | 100.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) 情况二.WHERE条件和ORDER BY中全部列都在索引中,索引最左列在WHERE条件中,
不管ORDER BY是ASC还是DESC,执行计划都可以完整用到索引。 mysql> desc SELECT * FROM titles WHERE emp_no='' AND title='Senior Engineer' order by from_date;
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | ref | PRIMARY | PRIMARY | 156 | const,const | 1 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' AND title='Senior Engineer' order by from_date desc;
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | ref | PRIMARY | PRIMARY | 156 | const,const | 1 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+---------+---------+-------------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' order by title,from_date;
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | ref | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' order by title,from_date desc;
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------------+
| 1 | SIMPLE | titles | NULL | ref | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using where; Using filesort |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-----------------------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE emp_no='' order by title desc,from_date desc;
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | titles | NULL | ref | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+---------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec) 情况三.当WHERE条件和ORDER BY中全部列都在索引中,索引最左列不在WHERE条件中而是在ORDER BY中
执行计划会走index。 mysql> desc SELECT * FROM titles WHERE title='Senior Engineer' order by emp_no,from_date;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 10.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE title='Senior Engineer' order by emp_no desc,from_date desc;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 10.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE from_date='1986-06-26' order by emp_no,title;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 10.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE from_date='1986-06-26' order by emp_no desc,title desc;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 10.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE title='Senior Engineer' AND from_date='1986-06-26' order by emp_no;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 1.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE from_date='1986-06-26' AND title='Senior Engineer' order by emp_no;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 1.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE title='Senior Engineer' AND from_date='1986-06-26' order by emp_no desc;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 1.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles WHERE from_date='1986-06-26' AND title='Senior Engineer' order by emp_no desc;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 1.00 | Using where |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------------+
1 row in set, 1 warning (0.00 sec) 情况四.当WHERE条件无过滤,索引列全在ORDER BY中
1.当order by 中ASC和DESC顺序和索引一致执行计划会走INDEX,如果不一致则会走全表扫描。 mysql> desc SELECT * FROM titles order by emp_no,title,from_date;
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------+
| 1 | SIMPLE | titles | NULL | index | NULL | PRIMARY | 159 | NULL | 441772 | 100.00 | NULL |
+----+-------------+--------+------------+-------+---------------+---------+---------+------+--------+----------+-------+
1 row in set, 1 warning (0.01 sec) mysql> desc SELECT * FROM titles order by emp_no,title desc,from_date desc;
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | titles | NULL | ALL | NULL | NULL | NULL | NULL | 441772 | 100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles order by emp_no desc,title,from_date;
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | titles | NULL | ALL | NULL | NULL | NULL | NULL | 441772 | 100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec) mysql> desc SELECT * FROM titles order by emp_no,title desc,from_date desc;
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
| 1 | SIMPLE | titles | NULL | ALL | NULL | NULL | NULL | NULL | 441772 | 100.00 | Using filesort |
+----+-------------+--------+------------+------+---------------+------+---------+------+--------+----------+----------------+
1 row in set, 1 warning (0.00 sec)
MySQL联合索引最左匹配范例的更多相关文章
- MySQL 联合索引详解
MySQL 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分.例如索引是key index (a,b,c ...
- mysql 联合索引(转)
http://blog.csdn.net/lmh12506/article/details/8879916 mysql 联合索引详解 联合索引又叫复合索引.对于复合索引:Mysql从左到右的使用索引中 ...
- SQL Server中的联合主键、聚集索引、非聚集索引、mysql 联合索引
我们都知道在一个表中当需要2列以上才能确定记录的唯一性的时候,就需要用到联合主键,当建立联合主键以后,在查询数据的时候性能就会有很大的提升,不过并不是对联合主键的任何列单独查询的时候性能都会提升,但我 ...
- MySQL联合索引VS单列索引
MySQL联合索引VS单列索引 以一个一千万数据量的表格为例 1. 建表建索引 USE foo; DROP TABLE IF EXISTS tmp; CREATE TABLE tmp ( id INT ...
- [转]mysql联合索引
mysql联合索引 命名规则:表名_字段名1.需要加索引的字段,要在where条件中2.数据量少的字段不需要加索引3.如果where条件中是OR关系,加索引不起作用4.符合最左原则 https:/ ...
- 我说MySQL联合索引遵循最左前缀匹配原则,面试官让我回去等通知
面试官: 我看你的简历上写着精通MySQL,问你个简单的问题,MySQL联合索引有什么特性? 心想,这还不简单,这不是问到我手心里了吗? 听我给你背一遍八股文! 我: MySQL联合索引遵循最左前缀匹 ...
- 三道MySQL联合索引面试题,淘汰80%的面试者,你能答对几道
众所周知MySQL联合索引遵循最左前缀匹配原则,在少数情况下也会不遵循(有兴趣,可以翻一下上篇文章). 创建联合索引的时候,建议优先把区分度高的字段放在第一列. 至于怎么统计区分度,可以按照下面这种方 ...
- MySQL联合索引运用-最左匹配原则
前言 之前看了很多关于MySQL索引的文章也看了<高性能MySQL>这本书,自以为熟悉了MySQL索引使用原理,入职面试时和面试官交流,发现对复合索引的使用有些理解偏颇,发现自己的不足整理 ...
- mysql 联合索引匹配原则
读mysql文档有感 看了mysql关于索引的文档,网上有一些错误的博客文档,这里我自己记一下. 几个重要的概念 1.对于mysql来说,一条sql中,一个表无论其蕴含的索引有多少,但是有且只用一条. ...
随机推荐
- python爬虫之User-Agent用户信息
python爬虫之User-Agent用户信息 爬虫是自动的爬取网站信息,实质上我们也只是一段代码,并不是真正的浏览器用户,加上User-Agent(用户代理,简称UA)信息,只是让我们伪装成一个浏览 ...
- quartz使用(整合spring)
quartz与spring整合后,还是需要Scheduler实例.JobDetail实例.Trigger实例,只不过是用FactoryBean的方式创建了. 在spring-context-suppo ...
- mysql DML语句
1, 插入数据 insert into emp1(ename,hiredate,sal,deptono) values('kingle','2000-01-01','2000',1); 插入数据加入需 ...
- golang context 剖析 1.7.4 版本
1. 内部结构之 - timerCtx . type timerCtx struct { cancelCtx timer *time.Timer // Under cancelCtx.mu. dead ...
- 【原】shell编写一个简单的jmeter自动化压测脚本
在公司做压力测试也挺长时间了,每次测试前环境数据准备都需要话费较长时间,所以一直在考虑能不能将整个过程实现自动化进行,于是就抽空写了一个自动化脚本,当然这个脚本目前功能十分简陋,代码也不完善,很有很多 ...
- 关于GBK、GB2312、UTF8之间的区别
UTF-8:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM.是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为( ...
- LINQ和.NET数据访问
.NET数据访问 在.NET中对于数据的访问大致有三个层面,数据访问层.内存数据集.业务逻辑层.数据层,包括了XML配置文件以及一些常用的数据库(使用SQL语句):内存数据集,主要是DataSet数据 ...
- MyEclipse 中tomcat 调试时进入未打断点的代码
在preferences里面取消挂起未捕获异常
- C#学习笔记7
1.重写GetHashCode方法注意点: (1)重写GetHashCode方法,也应重写Equals方法,否者编译器会警告. (2)相等的对象必须有相等的散列码(若a.Equals(b),则a.Ge ...
- Csharp:asp.net CheckBoxList databind
/// <summary> /// CheckBoxList數據源 /// 塗聚文 /// 20130705 /// /// </summary> private void s ...