聚簇索引:(非索引类型,只是一种数据存储方式) 表数据按照索引顺序存储,叶子结点存储了真实数据行,一张表上面最多只能创建一个聚簇索引。
如图:叶子页中包含了行的全部数据,但是节点页只包含了索引列。
其他非聚簇索引的结构的,叶子节点中仍然是索引节点,只不过是有指向其对应数据块的指针。
优点:
- 可以把相关数据保存在一起,例如电子邮箱中,根据用户ID来聚集数据,这样就可以磁盘读取少量的数据页便可以读取到某个用户的全部邮件
- 数据访问更块,聚簇索引将数据和索引保存在同一个B-Tree中,直接能从聚簇索引中获取数据
缺点:
聚簇索引按照顺序存储且在叶子节点中存储真实数据行会导致数据更新等操作比较麻烦
- 插入速度依赖于插入顺序
- 更新聚簇索引代价很高
- 全表扫描很慢
如下表例子:
id | name | gender | total_score | city |
---|---|---|---|---|
1 | Jolly | Female | 500 | London |
2 | Jon | Male | 545 | Manchester |
3 | Sara | Female | 600 | Leeds |
4 | Laura | Female | 400 | Liverpool |
5 | Alan | Male | 500 | London |
6 | Kate | Female | 500 | Liverpool |
7 | Joseph | Male | 643 | London |
8 | Mice | Male | 543 | Liverpool |
9 | Wise | Male | 499 | Manchester |
10 | Elis | Female | 400 | Leeds |
Sqlserver中可以选择索引作为聚簇索引,比如
CREATE CLUSTERED INDEX IX_tblStudent_Gender_Score ON student(gender ASC, total_score DESC)
根据用户的性别(gender)和总得分(total_score)创建聚簇索引,找所有记录的结果便会是:
id | name | gender | total_score | city |
---|---|---|---|---|
3 | Sara | Female | 600 | Leeds |
1 | Jolly | Female | 500 | London |
6 | Kate | Female | 500 | Liverpool |
4 | Laura | Female | 400 | Liverpool |
10 | Elis | Female | 400 | Leeds |
7 | Joseph | Male | 643 | London |
2 | Jon | Male | 545 | Manchester |
8 | Mice | Male | 543 | Liverpool |
5 | Alan | Male | 500 | London |
9 | Wise | Male | 499 | Manchester |
mysql 中并不支持自选索引作为聚簇索引,对于InnoDB,一般通过主键聚集数据,如果没有主键列,便会选择一个唯一的非空索引代替,如果没有这样的索引,InnoDB会隐式定义一个主键来作为聚簇索引。
覆盖索引: 一个索引包含所有需要查询的字段的值,我们称为覆盖索引。
需要查询字段的值,即覆盖索引必须要存储索引列的值。所以Mysql只能使用B-Tree索引做覆盖索引。