建立索引的目的是加快对表中记录的查找或排序。付出的代价:
1. 增加了数据库的存储空间
2. 在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。
一。索引分类
索引分为聚簇索引和非聚簇索引两种。
每个表只能有一个聚簇索引,因为一个表中的记录只能以一种物理顺序存放。但是,一个表可以有不止一个非聚簇索引。实际上,对每个表你最多可以建立
249个非聚簇索引。非聚簇索引需要大量的硬盘空间和内存。另外,虽然非聚簇索引可以提高从表中取数据的速度,它也会降低向表中插入和更新数据的速度。
每当你改变了一个建立了非聚簇索引的表中的数据时,必须同时更新索引。因此你对一个表建立非聚簇索引时要慎重考虑。如果你预计一个表需要频繁地更新数
据,那么不要对它建立太多非聚簇索引。另外,如果硬盘和内存空间有限,也应该限制使用非聚簇索引的数量。
二。区别
1. 聚簇索引的叶节点就是数据节点,而非聚簇索引的页节点仍然是索引检点,并保留一个链接指向对应数据块。
2. 聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多。
3. 相比之下,聚簇索引适合排序,非聚簇索引不适合用在排序的场合。因为聚簇索引本身已经是按照物理顺序放置的,排序很快。非聚簇索引则没有按序存放,
需要额外消耗资源来排序。
4. 当你需要取出一定范围内的数据时,用聚簇索引也比用非聚簇索引好。
三。建立聚簇索引的思想
1、大多数表都应该有聚簇索引或使用分区来降低对表尾页的竞争,在一个高事务的环境中,对最后一页的封锁严重影响系统的吞吐量。
2、在聚簇索引下,数据在物理上按顺序排在数据页上,重复值也排在一起,因而在那些包含范围检查(between、<、<=、>、>=)或使用group by或
order by的查询时,一旦找到具有范围中第一个键值的行,具有后续索引值的行保证物理上毗连在一起而不必进一步搜索,避免了大范围扫描。
3、在一个频繁发生插入操作的表上建立聚簇索引时,不要建在具有单调上升值的列上,否则会经常引起封锁冲突。
4、在聚簇索引中不要包含经常修改的列,因为码值修改后,数据行必须移动到新的位置。
5、选择聚簇索引应基于where子句和连接操作的类型。
四。聚簇索引的侯选列
1、主键列,该列在where子句中使用并且插入是随机的。
2、按范围存取的列,如pri_order > 100 and pri_order < 200。
3、在group by或order by中使用的列。
4、不经常修改的列。
5、在连接操作中使用的列。
五。MySQL 的聚簇索引
1. InnoDB使用B-Tree来实现聚簇索引,并把索引和数据存放在同一结构中。
2. 只有叶子节点才包括了数据行的值,非叶子节点只存了索引字段。
3. InnoDB只能按照主键做聚簇。如果表中没有定义主键,InnoDB会选择一个非空且有唯一性约束的索引来做聚簇,如果没有这样的索引,则会定义一个
不可见的主键,并以这个主键来聚簇。
4. InnoDB clusters records together only within a page. Pages with adjacent key values may be distant from each other.
InnoDB的聚簇是页面级别的,即聚簇索引值相邻的行会被存入同一个页面,当这个页面存满时,接下来的相邻行会被存入另外一个页面,而这两个页面可
能会离的很远。如图中的布局所示,索引值为1~10的行被存在第一个页面,11~20的行被存在另外一个页面,数据被聚簇在单个页面内,而页面1和页面2的磁盘
位置却可能离的很远。
聚簇索引 & 非聚簇索引