说明:本文为唯一索引和非唯一索引性能对比参考手册
用途:本文仅供初学者熟悉了解索引或优化参考
标签:Oracle优化、索引存储结构、唯一索引、非唯一索引、B树索引


  • 总结:唯一索引比非唯一索引性能更高
  • 应用:前期设计时尽量避让索引构建在免非唯一列上
  • 原理:

在非唯一索引中,数据库通过将rowid作为额外的列附加到键中来存储它。条目添加一个长度字节以使键唯一。

如下所示的非唯一索引中的第一个索引键是对0、rowid,而不仅仅是0。该数据库根据索引键值和rowid升序对数据进行排序。非唯一索引结构如下:

msyql 非唯一索引范围更新 oracle建非唯一索引_非唯一索引

在唯一索引中,索引键不包括rowid。数据库仅根据索引键值(如0、1、2等)对数据进行排序。唯一索引结构如下:

msyql 非唯一索引范围更新 oracle建非唯一索引_msyql 非唯一索引范围更新_02

  • B树索引结构(非唯一索引)
  • 索引存储如何影响索引扫描

位图索引块可以出现在索引段的任何位置。

上图显示了相邻的叶块。例如,1-10块在11-19块的旁边和前面。这个排序说明了连接索引项的链表。但是,索引块不需要按顺序存储在索引段中。例如,246-250块可以出现在片段中的任何位置,包括直接出现在1-10块之前。因此,有序索引扫描必须执行单块I/O。数据库必须读取一个索引块,以确定接下来必须读取哪个索引块。

索引块体在堆中存储索引项,就像表行一样。例如,如果值10首先插入到表中,那么键为10的索引项可能插入到索引块的底部。如果接下来将0插入到表中,那么键0的索引项可能会插入到10的项之上。因此,块体中的索引项不是按键顺序存储的。但是,在索引块中,行标头按关键顺序存储记录。例如,头中的第一个记录指向键为0的索引条目,依此类推,直到指向键为10的索引条目的记录。因此,索引扫描可以读取行标头,以确定从哪里开始和结束范围扫描,避免必须读取块中的每个条目。