Skip to content

Commit b05c498

Browse files
author
chengwei2
committed
update
1 parent 0c9a3e8 commit b05c498

2 files changed

Lines changed: 43 additions & 13 deletions

File tree

_posts/2017-10-22-数据库索引技术.md

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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是聚集索引组织表,它的聚集索引选择规则是:主键索
5673
3.hash索引只能用于比较查询 = 或 IN,其他范围查询无效,本质还是因不存储表数据;
5774
4.一旦出现碰撞,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)
268 KB
Loading

0 commit comments

Comments
 (0)