索引

1. 索引是一种数据结构,基于数据库表创建,包含一个表中某些列的值以及记录对应的地址,目的是为了优化查找速度。

2. 索引结构的实现方式:

  1. 二叉查找树,红黑树:相对于B族树而言,深度高,逻辑相邻的节点实际存储可能分散很远,需要多次IO读取,效率低。
  2. B树:每个节点大小设计为一页,一次IO能全部读取,充分利用了磁盘预读。深度低,IO次数少。
  3. B+树:叶子节点包含所有的节点,支持叶子顺序遍历,方便范围查找。非叶子节点没有指向数据的引用,故一个节点可以存储更多的关键字。
  4. HashMap: 将键值换算为哈希值,等值查询下速度非常快,但是范围查询(模糊查询)就毫无用武之地了,另外,在大量重复键值的情况下,效率非常低。

      关于B树结构的不同,详细请参考:https://blog.csdn.net/mine_song/article/details/63251546

  关于HashMap和B数索引的区别:http://imysql.com/2016/01/06/mysql-faq-different-between-btree-and-hash-index.shtml

3. 聚集索引/非聚集索引

  聚集索引:索引列排列的逻辑顺序和数据行的物理存储顺序一致,一个表中只能有一个聚集索引,叶子节点是数据节点。类似于字典中的拼音查询,适合范围查询。

  非聚集索引:不满足聚集索引条件的其他索引,一个表可以有多个非聚集索引,类似于字典中的部首查询。

4. 非聚集索引的二次查询

  非聚集索引叶子节点依然是索引节点,只是有一个指针指向对应的数据块。当查询包含不在索引中的列时,需要进行第二次查询以找到对应的数据。

#非聚集索引username
select username, score from t_student where username = '小明';

  解决方法:使用复合索引,建立两列以上的索引。

  详细请参考:https://www.cnblogs.com/aspnethot/articles/1504082.html

3. MySQL索引的实现

  针对不同的存储引擎,索引的实现方式是不同的,一下介绍 MyISAMInnoDB 两个存储引擎的实现。

  1. MyISAM使用B+树作为索引结构,叶子节点的data域存放的是数据记录的地址。

  1)主键索引(Col1)

  

  2)辅助索引(Col2)

  

  在MyISAM中,主索引和辅助索引在结构上没有区别,唯一不同的是主索引要求key唯一,辅助索引可以重复。MyISAM的索引方式是非聚集的。

  2. InnoDB索引同样使用B+树

  1)主键索引(叶子节点包含完整数据记录,是聚集索引)

  

  2)辅助索引(引用主键作为data域,是非聚集索引,使用辅助索引查询需要两遍检索:获得主键+在主键中获得数据)

  

 

4. 最左前缀原理

https://www.cnblogs.com/big-handsome-guy/p/7755059.html

  创造联合索引时(emp_no, title, from_date),上表存在主键索引emp_no(index 1), title(index 2), from_date(index 3)。查询语句按照最左前缀原理,按照index顺序从1开始往后使用连续的一段索引,如果中间缺少某个索引,则之后的索引都不会用到(除非额外添加辅助索引)。

  存在一下几种情况:

  1. 全列匹配:按照索引中所有列精确匹配("="/"IN"),索引可以被用到,且会自动优化顺序
  2. 最左前缀匹配:查询语句精确匹配索引锁边连续的一个/多个列时,只用到一部分
  3. 中间某条件未提供:之后的索引均不会被用到,可以使用辅助索引连接断开的两端或者使用“隔离化”优化方法
  4. 没有指定第一列:所有索引均不会用到
  5. 匹配某列的前缀字符串:通配符%不能出现在开头
  6. 范围查询:范围列可以用到索引(必须是最左前缀),且只能用于一个范围列,范围列之后的列无法用到索引(是建立索引时的顺序而不是查询顺序!!)。
  7. 查询语句中含有函数或表达式:该列不使用索引

  那么为什么会遵循最左匹配原理呢?

  以B+树作为索引来理解,建立联合索引时靠左边的索引在树的节点位置中靠上,而查找时是按照节点从上到下的顺序进行的,所以会有最左匹配原则。

  

5. 索引选择性和前缀索引

  索引本身需要存储空间,其次,数据的插入删除修改也需要更新索引,一般下面两种情况不建议使用索引:

  1. 表的记录较少,此时直接全表扫描
  2. 索引的选择性(不重复的索引值/表记录数)较低
  3. 文本格式的字段

  InnoDB主键索引建议设定自增,减少索引的维护。

  在下面几种情况下,推荐添加索引:

  1. 经常需要搜索的列

  2. 作为主键的列

  3. 经常需要范围搜索的列

  4. 经常需要排序的列

参考:http://blog.codinglabs.org/articles/theory-of-mysql-index.html

  

  

  

posted @ 2018-08-02 16:52  walker993  阅读(111)  评论(0编辑  收藏  举报