使用存取方法伪指令来指定优化程序搜索表的方式。
用逗号或空格来分隔括号中的元素。
关键字 | 作用 | 优化程序的操作 |
---|---|---|
AVOID_FULL | 列出的表没有全表扫描 | 优化程序考虑它能扫描的不同索引,如果没有索引,优化程序执行全表扫描。 |
AVOID_INDEX | 不使用任何列出的索引 | 优化程序考虑剩余的索引和全表扫描。如果一个表的所有索引都指定了,优化程序就使用全表扫描来访问表。 |
AVOID_INDEX_SJ | 对指定的索引不使用索引自连接路径 | 优化程序不考虑用于在索引自连接路径中扫描表的指定索引。 |
AVOID_MULTI_INDEX | 对指定的表不使用多索引扫描 | 优化程序不考虑指定表的多索引扫描路径。 |
FULL | 实行全表扫描 | 即使一列存在一个索引,优化程序也使用全表扫描来访问表。 |
INDEX | 使用指定的索引来访问表 | 如果指定了多个索引,优化程序会选择产生最小成本的索引。如果没有指定索引,那么所有可用的索引都会被考虑。 |
INDEX_ALL 或 MULTI_INDEX | 使用指定索引来访问表(多索引扫描) | 这些关键字是同义词。有关其用法信息,请参阅下面的“多索引扫描”。 |
INDEX_SJ | 使用指定使用扫描索引自连接路径中的表 | 优化程序被强制使用具有指定索引的索引自连接路径(或者索引自连接路径在索引列表中选择成本最低的索引)扫描表。 |
AVOID_FULL 和 INDEX 关键字都表示优化程序应该避免全表扫描。然而,建议使用关键字 AVOID_FULL 来表示避免全表扫描的意图。
AVOID_MULTI_INDEX 伪指令不接受索引的列表作为它的参数。这是因为 AVOID_INDEX 伪指令还会阻止在多索引扫描执行路径中使用指定的索引。
可在表上定义多达十六个(16)索引。基于在同一表上使用多个索引的访问方法的搜索路径被称为多索引扫描。 MULTI_INDEX 或 INDEX_ALL 伪指令强制查询优化程序考虑多索引扫描以搜索指定的表以进行限定。MULTI_INDEX 或 INDEX_ALL 指令的参数列表具有以下语义:
多索引扫描路径通过跳过扫描访问方法使用 ROWID 的排序列表访问。排序列表通常使用 INDEX_ALL 或 MULTI_INDEX 指令指定的所有索引从多索引扫描存取方法生成。
例如,如果查询谓词指定 col1 <= 10 和 col2 BETWEEN 15 AND 25,则执行计划可以使用两个索引:col1 上的第一个索引,col2 上的第二个索引。每个索引扫描返回满足相应索引的搜索条件的所有 ROWID。ROWID 的两个列表的逻辑交叉仅包括满足两个搜索条件的行。然后,数据库服务器对组合的 ROWID 列表进行排序,并使用此排序列表来扫描表查询的结果集。
如果查询包含多于两个索引列的谓词,则每个索引扫描返回的 ROWID 列表必须合并,以生成所有限定行的排序 ROWID 列表。
因为每个 ROWID 表示一行的物理位置(在哪个页面上和哪个 slot 中),执行路径简单地访问该物理位置以检索该行。由于术语 "skip-scan" 建议,在排序列表中通常存在从一个 ROWID 到下一个 ROWID 的间隙,是的数据库服务器从结果集合的一个合格行“跳过”到下一个合格行。
Skip-scan 存取方法类似于顺序扫描,但是有时可能更有效。顺序扫描检索表中的每一行,但跳过扫描只检索限定的 ROWID 的行。
事务隔离级别影响 MULTI_INDEX 或 INDEX_ALL 伪指令是否可强制多索引扫描执行路径,当隔离级别为 Cursor Stability 时,或者使用 LAST COMMITTED 选项的 Committed Read 时无效。(但是,在 Dirty Read 和 Repeatable Read 隔离级别,和不带有 LAST COMMITTED 选项的 Committed Read 隔离级别中支持这些伪指令)。
通常,您只能为一个表指定一个存取方法。只有下列存取方法伪指令的组合在同一查询的同一表中有效:
当指定 AVOID_FULL 和 AVOID_INDEX 存取方法伪指令时,优化程序避免表的全表扫描并且它避免使用指定的索引。此负指令的组合允许优化程序使用指定的存取方法伪指令之后创建的索引。
因为如果指定 INDEX 或 AVOID_FULL 伪指令,优化程序会自动考虑索引自连接路径,所以 INDEX_SJ 伪指令只是强制使用指定索引的索引自连接路径(或者在逗号分隔的列表中选择成本最低的索引的索引)。当多列索引包括仅提供低选择性的列作为索引键过滤时,INDEX_SJ 伪指令可以提高性能。
指定 INDEX_SJ 伪指令规避了索引引导键上数据分布统计信息的常见优化程序要求。此指令使优化程序考虑索引自连接路径,即使数据分布统计信息不可用于索引键列。在这种情况下,优化程序仅包括索引键列的最小数量作为满足指令的引导键。
例如,如果在列 c1 、c2 、c3 、c4 上定义了索引,并且查询为这四个列指定了过滤器,但没有数据分布在任何列上可用,则在此索引上指定 INDEX_SJ 会导致列 c1 被用作索引自连接路径中的引导键。如果希望优化程序使用索引但不考虑索引自连接路径,则必须指定 INDEX 或 AVOID_FULL 伪指令选择索引,并且还必须指定 AVOID_INDEX_SJ 伪指令以防止优化程序考虑任何其它索引自连接路径。
如果 AVOID_INDEX_SJ 与 INDEX 伪指令一起使用,作为显式 INDEX 或等效的 AVOID_FULL 和 AVOID_INDEX 组合,则 AVOID_INDEX_SJ 伪指令中指定的索引必须是 INDEX 伪指令中指定的索引的子集。有关 INDEX_SJ 和 AVOID_INDEX_SJ 伪指令的作用的更多信息,请参阅描述优化程序伪指令的 GBase 8s 性能指南 一章。
指定 MULTI_INDEX 或 INDEX_ALL 伪指令规避了指定表上统计信息的常见优化程序要求。在考虑表上的多索引扫描路径之前,优化程序通常至少需要对表进行低级统计。
SELECT {+INDEX(emp idx_dept_no)} ...
在上述示例中,此存取方法伪指令强制优化程序考虑扫描 dept_no 列上的 idx_dept_no 索引的执行路径。
在下面的示例中,存取方法伪指令强制优化程序考虑使用多索引扫描,它是基于扫描 dept_no 列上的 idx_dept_no 索引和 job_no 列上的 idx_job_no 索引的组合结果。
SELECT {+MULTI_INDEX(emp idx_dept_no ids_job_no)} ...
SELECT {+AVOID_INDEX(emp idx_loc_no, idx_job_no), AVOID_FULL(emp)} ...
该示例包含多个存取方法伪指令。这些伪指令通过指示优化程序不扫描 idx_loc_no 和 idx_job_no 索引,页不执行 emp 表的全表扫描来强制扫描 dept_no 列的 idx_dept_no 索引。但是,如果为表 emp 创建了一个新的 idx_emp_no ,则这些伪指令不会阻止优化程序考虑它。
还请注意,术语负指令引用存取方法伪指令中的字符串 "AVOID_" ,并且与开始每个优化程序指令的注释指示符之后的 + 号无关。