您的位置:首页 > 数据库 > MySQL

mysql 索引总结

2015-11-02 10:38 330 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/lpfwenwen/article/details/49583681

      mysql 索引 包括“普通索引”、“唯一索引”、“全文索引”、“主键索引”,主要目的是为了提高查询性能(通过explain select * from table where col_index = 'xxx' 来对比添加索引前后的查询时间)

     对于MySQL的Innodb储存引擎来说,大部分类型的index均以B-Tree数据结构的变种B+Tree来存储(MEMORY类型的表还支持hash类型的索引)。B-Tree是数据库或文件系统中常用的一种数据结构,它是一种N叉平衡树,这种树结构保证了同层节点保存的key有序,对于某个节点来说,其左子树保存的所有key均小于该节点保存的key,其右子树保存的所有key均大于该节点保存的key。此外,在工程实现上,还结合操作系统的局部性原理做了很多优化,总之,b-tree的各种特性或优化技巧能保证:1) 查询磁盘记录时,读盘次数最少;2) 任何insert和delete操作对树结构的影响均很小;3) 树本身的rebalance操作很高效。

一、mysql 索引

     1.普通索引.

(1)EXPLAIN  select * from `table_name` where   `begin_date` =>  'xxx'   and    `begin_date` <=  'xxx'   

[SQL]EXPLAIN select * from mp where mpmph IS not NULL limit 1,1
受影响的行:
时间: 0.xxx秒

(2) ALTER TABLE `table_name` ADD INDEX index_name ( `begin_date`, `end_date`)

              EXPLAIN  select * from `table_name` where   `begin_date` =>  'xxx'   and    `begin_date` <=  'xxx'

     [SQL]EXPLAIN select * from mp where mpmph IS not NULL limit 1,1
     受影响的行:
     时间: 0.xxx秒

     2.唯一索引.

ALTER TABLE `table_name` ADDUNIQUE( `column`) 

  唯一索引通常是为了避免在插入数据时提交重复数据

     3.全文索引.

ALTER TABLE `table_name` ADD FULLTEXT ( `column`) 

     4.主键索引.

ALTER TABLE `table_name` ADDPRIMARY KEY( `column`) 

二、MySQL在以下操作场景下会使用索引:
(1) 快速查找符合where条件的记录
(2) 快速确定候选集。若where条件使用了多个索引字段,则MySQL会优先使用能使候选记录集规模最小的那个索引,以便尽快淘汰不符合条件的记录。
(3) 如果表中存在几个字段构成的联合索引,则查找记录时,这个联合索引的最左前缀匹配字段也会被自动作为索引来加速查找。
例如,若为某表创建了3个字段(c1, c2, c3)构成的联合索引,则(c1), (c1, c2), (c1, c2, c3)均会作为索引,(c2, c3)就不会被作为索引,而(c1, c3)其实只利用到c1索引。
(4) 多表做join操作时会使用索引(如果参与join的字段在这些表中均建立了索引的话)
(5) 若某字段已建立索引,求该字段的min()或max()时,MySQL会使用索引
(6) 对建立了索引的字段做sort或group操作时,MySQL会使用索引

从MySQL官网文档"Comparison of B-Tree and Hash Indexes"可知,下面这些类型的SQL可能会真正用到索引:

(1) B-Tree可被用于sql中对列做比较的表达式,如=, >, >=, <, <=及between操作

(2) 若like语句的条件是不以通配符开头的常量串,MySQL也会使用索引
比如,SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%'或SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%'可以利用索引,而SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'(以通配符开头)和SELECT * FROM tbl_name WHERE key_col LIKE other_col(like条件不是常量串)无法利用索引。
对于形如LIKE '%string%'的sql语句,若通配符后面的string长度大于3,则MySQL会利用Turbo Boyer-Moore algorithm算法进行查找。

(3) 若已对名为col_name的列建了索引,则形如"col_name is null"的SQL会用到索引

(4) 对于联合索引,sql条件中的最左前缀匹配字段会用到索引,示例请参考本文第2节第3条对联合索引的说明

(5) 若sql语句中的where条件不只1个条件,则MySQL会进行Index Merge优化来缩小候选集范围

三、hash 索引结构和B-Tree 索引结构区别(摘抄部分):

hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 Hash 索引的查询效率要远高于 B-Tree 索引。虽然 Hash 索引效率高,但是 Hash 索引本身由于其特殊性也带来了很多限制和弊端,主要有以下这些。
(1)Hash 索引仅仅能满足"=","IN"和"<=>"查询,不能使用范围查询
Hash 索引比较的是进行 Hash 运算之后的 Hash 值,所以它只能用于等值的过滤,不能用于基于范围的过滤,因为经过相应的 Hash 算法处理之后的 Hash 值的大小关系,并不能保证和Hash运算前完全一样。
(2)Hash 索引无法被用来避免数据的排序操作。
由于 Hash 索引中存放的是经过 Hash 计算之后的 Hash 值,而且Hash值的大小关系并不一定和 Hash 运算前的键值完全一样,所以数据库无法利用索引的数据来避免任何排序运算;
(3)Hash 索引不能利用部分索引键查询。
对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一起计算 Hash 值,而不是单独计算 Hash 值,所以通过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也无法被利用。
(4)Hash 索引在任何时候都不能避免表扫描。
Hash 索引是将索引键通过 Hash 运算之后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,由于不同索引键存在相同 Hash 值,所以即使取满足某个 Hash 键值的数据的记录条数,也无法从 Hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
(5)Hash 索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高。
对于选择性比较低的索引键,如果创建 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会非常麻烦,会浪费多次表数据的访问,而造成整体性能低下。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: