标签:
广义上区分索引分为3部分: B-树索引, 位图索引, 索引组织表
位图索引适用于不经常进行更新, 插入和删除的列. 例如数据仓库中的人口统计信息的性别.
一般, 选择相对来说较少的数据时, 适用索引时比较正确的. 典型的基于索引的访问路径通常包含以下3步:
1) 遍历索引树并在将 SQL 语句中的谓语应用到索引列后收集叶子块的行编号
2) 使用行编号从表数据块中获取数据行
3) 在所获取的数据行上应用其余的谓语来得出最终的结果集.
如果在第1步中返回了大量的行编号, 第2步访问表数据块的代价就会更高, 对于来自索引叶子块的每一个行编号, 都需要访问表数据块. 并且这可能会导致多次物理I/O从而引起性能问题. 同时, 从物理上来说1次只能访问1个表数据块, 进一步放大了性能问题.
选择进行索引的最佳列对于提高SQL访问性能是非常关键的. 下面这些就是选择最优索引列时需要考虑的内容
在SQL语句中经常会声明 IS NULL 谓语, 空值不存储在某个单独列的索引中, 因此谓语 IS NULL 将不会使用单列索引, 但空值是存储在多列索引中的.
使用位图来表示列值的行编号, 另外如果是数据仓库, 需要定期加载数据, 需要在加载之前先删除位图索引, 然后再进行加载.
可以看到, Bitmap 实际上也是一个树结构, 只不过叶子节点存储的不是rowid, 而是 bitmap, 这个bitmap 是一个关于物理块的映射, 而且是多块映射. 所以, 当你修改数据时, 需要全部修改这个映射, 这是很耗时的事情.
表本身被组织为一个索引, 所有列存储在索引树自身中, 使用主键来访问数据行将只会包含索引访问, 访问高效, 因为只要访问索引就可以了, 但是同时, 在常规的表中, 每一行都有一个行编号, 一旦在表中建立了一行数据, 它们就不再移动(可能会有行连接或行迁移, 但行的头部不会移动), 不同的是, IOT数据行存储在索引结构自身中. 因此, 数据行可能由于DML运算而迁移到不同的叶子块中, 从而引起索引叶子块结构的分裂与合并. 即在 IOT 表中没有物理行编号
IOT 适合于具有下面特点的表
索引组织表是一种能够有效减少数据行较短且需要进行大量DML和select活动的表中额外索引的特殊结构, 但如果IOT主键列较长, 在其中加入次级索引可能会增大索引大小, 重做区大小以及撤销区大小.
索引也可以像表那样进行分区.
这种类型的索引更适合于引导列中具有重复值的列.
create index <index name> on <schema.table_name> ( col1 [,col2 … coln])
compress N storage-parameter-clause
compress N 表示压缩索引引导列书目, 例如 在一个3列索引中对两个引导列进行压缩, 可以声明子句 compress 2. 另外, 你只能对引导列进行压缩, 比如 你可以压缩前两列, 不能压缩第1列 和 第3列的组合.
列值 12345 在索引中存储为 54321, 因为列值是按照反向顺序存储的, 连续的列值将会存储在不同的索引叶子块中, 从而避免了右侧增长索引带来的资源争夺问题, 但是在表数据块中, 这些列值还是存储为 12345的.
反转键索引的两个问题
1) 反转键索引的范围扫描不能使用范围运算符 如 between, <> 等, 这是可以理解的, 因为索引范围扫描的基本假设就是列值按照逻辑键升序或降序来存储, 反转键索引由于列值按照反转顺序存储, 没有按照逻辑键的顺序来谓语违反了这个假设. 因此索引范围扫描不适用于反转键索引.
2) 反转键索引可能会人为的增加物理读取的次数, 因为列值被存储在很多个叶子块中, 而这些叶子块可能需要读取到缓冲区缓存来修改块.
所以, 有时, 你可能需要考虑分区索引, 而不是反转键索引.
索引默认按照升序存储列值, 但可以通过使用降序索引来切换为降序存储. 如果应用按照某个特定的顺序上百万次的获取数据, 则这类索引是非常有用的. 例如, 取自客户交易表的按照时间顺序逆序排列的客户数据.
个人感觉, 使用的也不多, 因为即便是升序索引, 你需要的是倒序输出, oracle 也会智能的做好优化.
在某些场合, 你可能需要增加一个索引来对SQL语句的性能进行调优, 但你不太确定索引所带来的负面影响. 不可见索引在以较小的风险来衡量新索引所带来的影响方面非常有用. 一个索引可以加入到数据库中并标记为不可见, 这样优化器就不会选用这个索引, 可以在确定某个索引没有负面影响或对执行计划乜有负面影响后将它标记为可见.
在数据库加入索引后, 你可以在会话中将 optimizer_use_invisible_indexes 参数设置为 true. 这样不会影响应用性能, 然后复查 SQL 语句的执行计划. 另一个用处是, 这种索引有助于在删除不适用的索引时用来降低风险, 从生产数据库中删除不适用的索引并不是令人愉快的经历, 可能之后却意外的认识到删除的索引在一个重要的报表中用到了. 即使在经过充分的分析之后, 也有可能被删除的索引在某个商务过程中是必须的, 而重建索引可能会导致应用停机. 从 oracle 11g 以来, 你可以将索引标记为不可见, 等过了几周之后, 如果没有任何进程要用到这个索引, 则可以较为安全的将其删除. 如果在标记为不可见后发现索引是需要的, 则可以很快的使用一个SQL语句来将索引还原为可见.
标签:
原文地址:http://www.cnblogs.com/moveofgod/p/4223361.html