这是数据库索引相关内容的第三篇
索引
目录:
- 什么是索引
- 索引的存储
- 聚簇索引和非聚餐索引
- 索引片
1. 什么是索引
索引对于数据库,相当于目录对应于图书,我们能通过索引快速的对数据库的内容进行定位。
当没有索引,或者没有一个合适的索引,在大量的表数据中查询,将是一场灾难;
2. 索引的存储
索引实际使用时其还是占用存储空间的;
就像目录也是占用了图书的几页纸一样。
那么索引,是如何存储的呢?
其实,索引的存储就是用我在B树是个什么玩意中介绍的B树方式或者其衍生(B+ B-)方式存储。
B树索引能高效的提高磁盘IO,特别是对与数据库这种数据量比较多的情况,肯定是希望比较少的磁盘读取及每次读取得到比较多的数据;B树就很好的满足了这种特性。
3.聚簇索引和非聚簇索引
聚簇索引是比较容易混淆的概念,在不同的数据库中,其代表的意义是不一样的。
一般我们认为聚簇索引有如下特性:
1> 聚簇索引确定表中数据的物理顺序
2> 每张表只能建一个聚簇索引
3> 当聚簇索引缺失时,默认主键为聚簇索引
4> 非聚簇索引叶子节点指向聚簇索引
由此看来,聚簇索引是非常珍贵的,当查询的条件正好是聚簇索引能覆盖的范围时,是非常快速的;因为通过索引就能找到数据,不用再到磁盘上进行多次查找。
非聚簇索引,则是相反,其不限制个数,不能直接定位到数据,其叶子节点是指向数据的指针,且并不一定能唯一确定一条数据,所以指针可以是多个。
4.索引片
查询时,理想的情况是,查询条件已经覆盖在索引中了,查询是基于索引的查询,那此时查询速度会比较快;但是实际情况却很复杂,这就需要我们知道优化器是如何根据查询条件及索引来进行查询的。流程如下:
从头到尾依次检查索引列
1.在where子句中,该列是否至少拥有一个足够简单的查询与之对应?
如果有,那么这个列就是匹配列;
如果没有,那么这个列及其后面的索引列都是非匹配列
2.如果该索引对应的查询条件是范围,那么剩余的索引都是非匹配列
3.对于最后一个匹配列之后的索引列,如果拥有一个足够简单的查询条件与其对应,那么该列就是过滤列

比如索引(A,B,C,D),对应查询条件where A = 1 and B < 3 and C = 2
按照流程图,首先看A,A的查询语句是A = 1,足够简单,且不是范围条件,所以A是匹配索引
再看B,B是条件查询,B<3,所以B是匹配索引,但是B后面的索引都是非匹配索引;
再看查询条件,还有C=2,因为C虽然是索引,但是因为B是范围查询,所以其后的所有索引都是非匹配索引,所以C是非匹配索引,但是因为C也有简单的查询条件,所以C是过滤列
综上所述,对于索引(A,B,C,D),其在查询条件where A = 1 and B < 3 and C = 2中,索引片是(A,B)过滤列是C
那这个结果意味着什么?
也就是对于索引(A,B,C,D),其本身索引存储时,是 A, B, C, D
比如索引有100w条,那么根据上述流程图,A,B是索引片
那么基于这100W条,通过A,B组合查找出假设10w条,再通过C,在这10W条中进行过滤,最后剩余1w条
索引片越窄,即参与过滤的索引越多,那么效率就会越高,因为索引片本身的查找是基于索引的,即B树查找;
那是不是索引片窄了就行了呢?
其实索引涉及的内容还有很多,比如如果涉及到排序、联合查询、索引数目太多,什么才是好的索引等等
在此建议大家看《数据库索引设计与优化》(Tapio Lahdenmaki/Michael Leach)
通俗易懂的解释了索引的工作原理,以及如何设计索引
其他相关章节
数据库索引相关文章之一:《B树,一点都不神秘》
数据库索引相关文章之二:《B树很简单,插入so easy》
数据库索引相关文章之三:《索引》
数据库索引相关文章之四:《什么索引算是好的索引》
数据库索引相关文章之五:《如何发现及替换不合适的索引》
数据库索引相关文章之六:《索引总结》