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 1SELECT * FROM tbl_name WHERE primary_key=1;SELECT * FROM tbl_nameWHERE primary_key_part1=1 AND primary_key_part2=2;
  1. 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_tableWHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_tableWHERE ref_table.key_column_part1=other_table.columnAND ref_table.key_column_part2=1;
  1. ref_or_null
    这种连接有点类似于ref, 但是查询行包含NULL值时,MySQL会作额外的查询。这种连接类型的优化最经常在解决子查询的时候使用。下面的例子,MySQL会使用ref_or_nulll连接处理ref_table:
SELECT * FROM ref_tableWHERE key_column=expr OR key_column IS NULL;
参见 8.2.1.6, “IS NULL 优化”.
  1. index_merge
    这种连接类型说明已经启用索引合并优化。这种场景下,输出行中的key列包含用于索引的列表,并且key_len显示索引使用的最长key parts。更多信息参见“索引合并优化”。

    1. range
      只有当行根据给定范围检索到时,使用一个索引查询这些行。输出行的key列表明使用哪个索引。key_len列显示使用最长的key part。这种连接ref列为NULL。
      当key列和一个常量使用”=”, “<>”, “>”, “>=”, “<”, “<=”, IS NULL, “<=>”, 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);
  1. index
    索引连接类型和ALL一样,除了扫描索引树。两种执行方式:
    如果索引在查询里是一个覆盖性的索引,并且能够查询表中所有满足的数据,只有索引树被扫描。这种场景下,Extra列会显示”Using index”。通常只走索引扫描比全表扫描要快很多,因为索引的数量通常比表中的数据量要少很多。全表扫描优化方案是通过读取索引并按照索引顺序检索数据。使用索引不会在Etra列显示。列使用单一索引时,MySQL使用这种连接类型。

    1. 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 索引分析相关推荐

  1. MySQL索引分析和优化(转)

    MySQL索引分析和优化(转) 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记 录,直至找到符 ...

  2. MySQL 索引分析除了 EXPLAIN 还有什么方法?

    作者 | adrninistrat0r 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 前言 对于非数据库开发人员而言,难以对MySQL源码进行分析或调试,接近一个黑盒,但MySQL提供 ...

  3. php mysql索引原理_加速PHP动态网站 关于MySQL索引分析优化

    本文主要讲述了如何加速动态网站的MySQL索引分析和优化. 一.什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第 ...

  4. MySQL索引分析扩展理解

    MySQL索引分析扩展理解 看了很多网上的一些资料,感觉MySQL的索引知识还是很多的,这一篇文章就用来自己对MySQL索引的其他理解和以前模糊的地方的一些总结. 1.MySQL的常见索引模型 有序数 ...

  5. mysql索引分析_MySQL索引分析和优化

    什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面 ...

  6. mysql索引分析和优化_MySQL索引分析和优化

    什么是索引? 索 引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的 所有记录,直至找到符合要求的记录.表 ...

  7. MySQL索引分析以及相关面试题

    可以在我的个人博客阅读文章,排版会美观一些:文章地址 1. 什么是索引 一种能帮助mysql提高查询效率的数据结构:索引数据结构 索引优点: 大大提高数据查询速度 索引缺点: 维护索引需要耗费数据库资 ...

  8. mysql 索引分析工具_Mysql:性能分析以及Explain工具的使用

    ---恢复内容开始--- 1.介绍 Explain工具是用来分析sql语句性能的工具,他会显示出Mysql内部解析语句的状况 使用方法: explain+sql语句 例如 2.字段分析 一.ID字段 ...

  9. MySql索引分析及查询优化

    B-Tree 核心特点: 多路,非二叉树 每个节点既保存索引,又保存数据 搜索时相当于二分查找 B+Tree 核心特点 多路非二叉 只有叶子节点保存数据 搜索时相当于二分查找 增加了相邻接点的指向指针 ...

  10. MySQL索引 专题

    什么是索引 索引是存储引擎用于快速找到记录的一种数据结构,索引类似一本书的目录,我们可以快速的根据目录查找到我们想要的内容的所在页码,索引的优化应该是对查询性能优化最有效的手段了. 因此,首先你要明白 ...

最新文章

  1. 解决Mysql复制Relay log read failure 的问题
  2. oracle 创建用户、授权、表空间
  3. 【Python-ML】神经网络-深度学习库Keras
  4. CentOS 7 安装Boost 1.61
  5. python之初体验(一)
  6. c语言af-1,单反对焦模式中的AF-S、AF-C、AF-A是什么意思,
  7. Linux nohup和的功效
  8. Apache Flink 在京东的实践与优化
  9. 以后的blog将转移到微信公众号,请扫码关注谢谢!
  10. 循环首次适应算法_数据结构与算法之2——排序问题
  11. 读书笔记 - 《漫威宇宙》
  12. markdown 常用语法格式
  13. pcb布线注意点:晶振
  14. 手机端电子签名画板js插件
  15. Cisco Packet Tracer思科模拟器单臂路由的配置
  16. 计算机公式大小写,Excel表格金额大小写转换公式设置
  17. MCS9865串口卡并口卡驱动
  18. mongodb数据检索大全
  19. java 熄灯问题_Java算法应用之熄灯问题解决
  20. 全新三维成像技术:我们离科幻故事里的立体投影又近了一步

热门文章

  1. influxDB的安装和简单使用
  2. 深入理解Java虚拟机运行时数据区
  3. 黑马安卓74期Android基础(0)
  4. apiCloud中aui获取不到高度,pos.h为0,offsetHeight为0问题
  5. docker使用官方仓库上传与下拉images
  6. win7 64位Apache http server+PHP配置
  7. bzoj 1926: [Sdoi2010]粟粟的书架 (主席树+二分)
  8. 浅谈数据迁移测试(转载)
  9. 微信小程序学习笔记(阶段一)
  10. python 获取路径