MySQL复合唯一索引分析

关于复合唯一索引(unique key 或 unique index),网上搜索不少人说:”这种索引起到的关键作用是约束,查询时性能上没有得到提高或者查询时根本没有走索引列“。也有人说:“查询时使用到了索引和普通索引一样“。那么问题到底是怎样的呢?

测试准备工作

准备建表语句,插入数据等工作:

-- 建表(注:a,b是复合唯一索引)

create table test0(id bigint not null primary key auto_increment, a varchar(10) not null, b varchar(10) not null, unique index(a, b))engine=innodb charset=utf8 auto_increment=1;

-- 插入数据

insert into test0(a, b)values('china', 'chinese');

insert into test0(a, b)values('japan', 'japanese');

insert into test0(a, b)values('germany', 'german');

insert into test0(a, b)values('korea', 'korea');

insert into test0(a, b)values('france', 'frence');

insert into test0(a, b)values('australia', 'australia');

insert into test0(a, b)values('america', 'american');

insert into test0(a, b)values('brazil', 'brazil');

-- 执行计划一(查询存在纪录)

explain select * from test0 where a='france' and b='frence';

-- 执行计划二(查询不存在纪录)

explain select * from test0 where a='france' and b='america';

执行计划一:

执行计划二:

综上可以看出:

执行计划一,查询条件匹配时命中所有的索引;

执行计划二,查询条件不匹配时没有命中索引,并返回一条Extra”Impossible WHERE noticed after reading const tables”

那么到底这两次查询有什么不同呢?

MySQL关于这种索引的执行计划以及优化方案是什么?

我不得不把官方的Doc阅读一遍,关键点总结如下:

Explain join types 执行计划”type”列表,从执行性能最好到最坏:

1. system

表中只有一行数据(=system table)。这是常数连接类型的特例。

2. const

在查询开始时读取表时仅有一行可以匹配的数据。因为仅匹配到一行数据,所以值列可以被认为是常数级优化。常数表查询非常快因为它们只读取一次就能命中。

常数类型仅仅在匹配”PRIMARY KEY”或者”UNIQUE INDEX”所有的列值时才会被使用。

下面的查询,表被当成常数表执行:

-- query 1

SELECT * FROM tbl_name WHERE primary_key=1;

SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;

ref

所有带索引值匹配的行都从这张表读取各种组合的行从之前的表读取。如果连接使用key的只是最左前缀,或者key不是PRIMARY KEY和UNIQUE index使用ref(换句话说,如果连接跟进key值没有查询单行数据)。如果这个key值使用时匹配了仅仅少数的行,这就是一个比较好的类型。

ref 可以用在索引列,条件匹配时使用”=” 或者 “<=>”操作。下面的示例,MySQL 能够使用ref连接处理 ref_table:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1;

ref_or_null

这种连接有点类似于ref, 但是查询行包含NULL值时,MySQL会作额外的查询。这种连接类型的优化最经常在解决子查询的时候使用。下面的例子,MySQL会使用ref_or_nulll连接处理ref_table:

SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;

参见 8.2.1.6, “IS NULL 优化”.

index_merge

这种连接类型说明已经启用索引合并优化。这种场景下,输出行中的key列包含用于索引的列表,并且key_len显示索引使用的最长key parts。更多信息参见“索引合并优化”。

range

只有当行根据给定范围检索到时,使用一个索引查询这些行。输出行的key列表明使用哪个索引。key_len列显示使用最长的key part。这种连接ref列为NULL。

当key列和一个常量使用”=”, “<>”, “>”, “>=”, “”, BETWEEN, 或者IN()比较时使用range连接:

SELECT * FROM tbl_name WHERE key_column = 10;

SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;

SELECT * FROM tbl_name WHERE key_column IN (10,20,30);

SELECT * FROM tbl_name WHERE key_part1 = 10 AND key_part2 IN (10,20,30);

index

索引连接类型和ALL一样,除了扫描索引树。两种执行方式:

如果索引在查询里是一个覆盖性的索引,并且能够查询表中所有满足的数据,只有索引树被扫描。这种场景下,Extra列会显示”Using index”。通常只走索引扫描比全表扫描要快很多,因为索引的数量通常比表中的数据量要少很多。全表扫描优化方案是通过读取索引并按照索引顺序检索数据。使用索引不会在Etra列显示。列使用单一索引时,MySQL使用这种连接类型。

ALL

全表扫描。通常,应该通过添加索引避免全表扫描。

EXPLAIN Extra Information

The Extra column of EXPLAIN output contains additional information about how MySQL resolves the query. The following list explains the values that can appear in this column. If you want to make your queries as fast as possible, look out for Extra values of Using filesort and Using temporary.

1. Child of 'table' pushed join@1

This table is referenced as the child of table in a join that can be pushed down to the NDB kernel. Applies only in MySQL Cluster NDB 7.2 and later, when pushed-down joins are enabled. See the description of the ndb_join_pushdown server system variable for more information and examples.

2. const row not found

For a query such as SELECT ... FROM tbl_name, the table was empty.

3. Distinct

MySQL is looking for distinct values, so it stops searching for more rows for the current row combination after it has found the first matching row.

4. Full scan on NULL key

This occurs for subquery optimization as a fallback strategy when the optimizer cannot use an index-lookup access method.

5. Impossible HAVING

The HAVING clause is always false and cannot select any rows.

6. Impossible WHERE

The WHERE clause is always false and cannot select any rows.

Impossible WHERE noticed after reading const tables

MySQL has read all const (and system) tables and notice that the WHERE clause is always false.

mysql 唯一索引和复合索引 区别_MySQL复合唯一索引分析相关推荐

  1. mysql唯一索引和联合索引的区别_mysql中,索引,主键,唯一索引,联合索引的区别...

    索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度. ...

  2. mysql lucene 索引区别_MySQL和Lucene索引对比分析

    MySQL和Lucene都可以对数据构建索引并通过索引查询数据,一个是关系型数据库,一个是构建搜索引擎(Solr.ElasticSearch)的核心类库.两者的索引(index)有什么区别呢?以前写过 ...

  3. oracle索引与mysql区别_Mysql和ORACLE索引的实现方式

    B-Tree和B+Tree 目前大部分数据库系统及文件系统都采用B-Tree或其变种B+Tree作为索引结构. 首先,对单个节点来说,是一个key value结构,key是作引的列,value有两种, ...

  4. mysql聚集索引可以多列吗_MySQL使用单列索引和多列索引

    讨论MySQL选择索引时单列单列索引和多列索引使用,以及多列索引的最左前缀原则. 1. 单列索引 在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一.可以考虑使用索引的主要有两种类型的列:在W ...

  5. MySQL通过两表避免回表_mysql利用覆盖索引避免回表优化查询

    前言 说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml ...

  6. mysql+索引优化+查询优化+存储优化_mysql利用覆盖索引避免回表优化查询

    前言 说到覆盖索引之前,先要了解它的数据结构:B+树. 先建个表演示(为了简单,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml ...

  7. mysql记录锁与互斥锁区别_MySQL的各种锁认知

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...

  8. mysql复合索引可以建多少个_MySQL 复合索引

    一. 1.索引越少越好,在修改数据时,第个索引都要进行更新,降低写速度. 2.最窄的字段放在键的左边 3.避免file sort排序,临时表和表扫描. 二.复合索引的建立原则: 如果您很可能仅对一个列 ...

  9. mysql索引使增删变慢_mysql优化之索引篇

    mysql,对it打工人,这个几乎是必备的技能之一.mysql可以解决我们平时工作中的大量的.有关增删查改的问题.所以想深入了解mysql,我觉得关键在于他的增删查改背后的算法,开搞. 面对增删查改等 ...

最新文章

  1. shell逻辑判断式与表达式
  2. 利用smarty生成静态页的关键代码
  3. 【Xamarin挖墙脚系列:代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧(转)】...
  4. 户外lisp导向牌如何安装_深圳医院导向标识牌制作按功能可分为哪些?
  5. 部署Zipkin分布式性能追踪日志系统的操作记录
  6. Cocos2d-x 发布 Android
  7. Java基础篇:如何应用接口?
  8. python中字符串方法总结
  9. mysql 主节点挂机_云服务器如何重启MySQL服务,正确重启mysql
  10. java 空文件夹删除_java创建文件文件夹,删除空文件夹,删除文件夹以及所有文件...
  11. vue项目中配置跨域
  12. 无线网服务器在哪里设置方法,无线网络如何设置静态ip地址
  13. 计算机改硬盘格式,硬盘格式转换,详细教您如何将硬盘mbr格式转换为gpt格式
  14. 微信小程序:全新强大的恋爱话术微信小程序源码土味情话视频号or自媒体操作项目
  15. Dem与遥感影像制作三维效果简单教程
  16. Beautiful Soup:4 kinds of objects
  17. linux ssh su - 区别,su 与 su -区别
  18. android 点击查看大图_你是不是遇到,在花瓣网部分图片详情页,点击“放大镜”无法预览高清大图?...
  19. 1525_AURIX TC275 BootROM上
  20. [庆国庆]来生情缘-温情女儿国

热门文章

  1. leetcode 853. 车队
  2. 背后的力量 | 推动政府数字化建设 华云数据为潜江市生态环境局搭建新一代企业级云平台
  3. 删除被删除的快捷方式中设置的快捷键
  4. Webdav文件大小限制解除
  5. qt可视化读取_生成_编辑_联动_保存目录树
  6. MMC无法创建管理单元,此单元可能没有正确安装
  7. mysql数据库迁移到瀚高数据库,包含数据迁移、sql语法、服务启动、部署、tomcat问题整理
  8. 工业用微型计算机课本习题答案,工业用微型计算机答案.doc
  9. Java 有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少?
  10. 计算机丢失divxdecoder.dll,divxdecoder.dll