@@ -17,23 +17,40 @@ tags:
1717* 聚集索引可以避免数据插入操作,集中于表的最后一个数据页面。
1818* 在某些情况下,索引可以避免排序操作。
1919
20- ## 最左前缀原则
21-
2220## 聚集索引
23- Mysql InnoDB的数据基于聚集索引存储。聚集索引的数据的物理存放顺序与索引顺序是一致的。
24- 在InnoDB表中,其聚集索引相当于整张表,而整张表也是聚集索引,主键必然是聚集索引,而聚集索引则未必是主键。
21+
22+ ![ 聚集索引] ( /img/collection/collection-framework-1.jpg )
23+
24+ 聚集索引表的数据按照索引的顺序存储。对于聚集索引,叶子结点是存储了真实数据的数据行,不再有单独的数据页。
25+ 在一张表上只能创建一个聚集索引,因为真实数据的物理顺序只可能是一种。
26+ 如果一张表没有聚集索引,name它被称为“堆集”(Heap)。这样的表中的数据行没有特定的顺序,所有的新行将被添加到表的末尾位置。
27+
28+ Mysql InnoDB的数据基于聚集索引存储。在InnoDB表中,其聚集索引相当于整张表,而整张表也是聚集索引。
2529每张InnoDB表只能创建一个聚集索引,聚集索引可以由一列或多列组成。
26- InnoDB是聚集索引组织表,它的聚集索引选择规则是:主键索引>非NULL唯一索引>ROWID。
30+ > InnoDB是聚集索引组织表,聚集索引由引擎自动选择,选择规则如下:主键索引>非NULL唯一索引>ROWID。
31+
2732首先选择显式定义的主键索引做为聚集索引;如果没有,则选择第一个不允许NULL的唯一索引;还是没有的话,就采用InnoDB引擎内置的ROWID作为聚集索引。
33+ ### 查询
34+ 通过聚集索引进行查询时,会进行N次数据页查询。同时查询通常是由磁盘获取,但在访问频率较高时,缓存会保存高层索引,此时查询有可能是从缓存读取。
35+ ### 插入
36+ 对于聚集索引表,在插入数据时,首先根据索引找到对应的数据页,如果该数据页未满,则挪到已有记录并插入数据;如果数据页已满,则需要新增和拆分数据页。
37+ 一般情况下,此时首先检查该数据页的数据段是否已满,如果数据段已满则分配新段,创建数据页并插入数据,然后调整索引指针,这需要将相应的索引页读入内存并加锁,如果该表还有非聚集索引,则需要更新这些索引指向新的数据页。
38+ 然而在某些特殊情况下会进行一些特殊处理,如果插入的记录很大,为了提高效率,会分配两个数据页,一个用来存储新纪录,另一个则用来存储拆分出来的记录,通常数据库系统会将重复的记录存储于相同的数据页中。
39+ ### 删除
40+ 对于聚集索引表,在删除数据时,首先找到记录删除数据,然后检查对应数据页是否为空,如果为空则回收该数据页;检查完数据页后再检查所在数据段,如果为空则回收该数据段;最后更新索引页(删除数据对应索引、合并索引)。
41+ > 索引合并:删除数据可能导致索引页中只有一条记录,该记录会被移至邻近的索引页,原索引页将被回收。
2842
2943## 非聚集索引
30- 聚集索引是一种索引组织形式,索引的键值逻辑顺序决定了表数据行的物理存储顺序;而非聚集索引则就是普通索引了,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序。
44+ 非聚集索引表的数据存储与索引顺序无关。对于非聚集索引,叶子结点包含索引字段值及指向数据页数据行的逻辑指针,该层紧邻数据页,其行数量与数据表行数量一致。
45+ ### 查询
46+ 通过非聚集索引查询时,会进行N-1次索引页的查询、1次数据页查询。同时查询通常是由磁盘获取,但在访问频率较高时,缓存会保存高层索引,此时查询有可能是从缓存读取。
47+ ### 插入
48+ 在插入数据时,如果表包含聚集索引,通过聚集索引查询插入位置并插入数据,同时更新非聚集索引;如果表不包含聚集索引,则插入到最末的数据页中,然后更新非聚集索引。
49+ ### 删除
50+ 删除数据时,首先找到记录删除数据,然后检查对应数据页是否为空,如果为空则回收该数据页;检查完数据页后再检查所在数据段,如果为空则回收该数据段;最后更新索引页(删除数据对应索引、合并索引)。
3151
32- ## 单列索引
33- 包含一列的索引称为单列索引
34-
35- ## 复合索引
36- 包含多列的称为复合索引,因为BTREE索引是顺序排列的,所以比较适合范围查询,但是在复合索引中,还应注意列数目、列的顺序以及前面范围查询的列对后边列的影响。
52+ ## 单列索引、复合索引
53+ 索引只包含一列的称为单列索引,而包含多列的索引称为复合索引,因为BTREE索引是顺序排列的,所以比较适合范围查询,但是在复合索引中,还应注意列数目、列的顺序以及前面范围查询的列对后边列的影响。
3754
3855## 索引类型
3956
@@ -56,10 +73,23 @@ InnoDB是聚集索引组织表,它的聚集索引选择规则是:主键索
56733.hash索引只能用于比较查询 = 或 IN,其他范围查询无效,本质还是因不存储表数据;
57744.一旦出现碰撞,hash索引必须遍历所有的hash值,将地址所指向数据一一比较,直到找到所有符合条件的行。
5875
59- # 参考文献
76+ ### BITMAP(Oracle)
77+ 如果索引列上不同值的个数比较少的时候,比如对于性别列(男或女)等,则使用位图索引会比较好,因为它对空间的占用非常少(因为都是用bit位来表示表里的数据行),从而在扫描索引的时候,扫描的索引块的个数也比较少。
78+ 注意:如果被索引的列经常被更新的话,则不适合使用位图索引。因为在更新索引条目的过程中,会锁定位图索引里多个索引条目。也就是同时只能有一个用户能够更新表T,从而降低了并发性。位图索引比较适合用在数据仓库系统里,不适合用在OLTP系统里。
79+
80+ ## 索引优化
81+ ### 最左前缀原则
82+
83+ ### 索引选择性与前缀索引
84+
85+ ### InnoDB的主键选择与优化
86+
87+ # 参考文献
88+ [ MySQL索引背后的数据结构及算法原理] ( https://www.cnblogs.com/tgycoder/p/5410057.html )
6089[ 数据库索引详解] ( http://www.cnblogs.com/gavinsp/p/5513536.html )
6190[ MySQL的聚集索引和非聚集索引] ( http://www.cnblogs.com/wyy123/p/6269875.html )
6291[ MySQL表为什么必须有主键 -- 聚集索引的简单介绍] ( http://blog.csdn.net/jhgdike/article/details/60579883 )
6392[ 聚集索引、非聚集索引、聚集索引组织表、堆组织表、Mysql/PostgreSQL对比、联合主键/自增长、InnoDB/MyISAM(引擎方面另开一篇)] ( https://www.cnblogs.com/charlesblc/p/5983234.html )
6493[ 聚集索引和非聚集索引(整理)] ( http://www.cnblogs.com/aspnethot/articles/1504082.html )
65- [ Mysql技术内幕——InnoDB存储引擎] ( https://jingyan.baidu.com/article/fedf07377c493f35ac89770c.html )
94+ [ Mysql技术内幕——InnoDB存储引擎] ( https://jingyan.baidu.com/article/fedf07377c493f35ac89770c.html )
95+ [ oracle索引原理(b-tree,bitmap,聚集,非聚集索引)] ( http://blog.csdn.net/chenleixing/article/details/48153295 )
0 commit comments