Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC
  IE5LYMWlmdvL 2023年11月30日 16 0

INDEX_SS提示的作用和使用方法

INDEX_SS提示是指导优化器,通过索引跳跃扫描的方式来访问指定的索引。所谓跳跃扫描,是指跳过索引前导列来对索引进行访问。所以,发生跳跃扫描的索引,一定是2列及以上列构成的组合索引。

INDEX_SS提示的使用语法如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_sql优化

INDEX_SS_ASC和INDEX_SS_DESC是指在索引跳跃扫描的前提下,以正序(ASC)或倒序(DESC)的方式来访问。在未指定是的正序还是倒时,默认的是正序访问。

INDEX_SS_ASC提示的使用语法如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_倒序_02

INDEX_SS_DESC提示的使用语法如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_index_ss_03

其中:
tablespec表示目标表的名称或别名(当有别名时,必须用别名)。但不要加入表的属主(SCHEMA)名,哪怕在SQL中,明确写了属主,提示中也不能写。

indexspec表示要使用哪个索引,或者要在哪个列上使用索引。其语法图如下所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_04

queryblock表示查询块。优化器在为一条SQL制定执行计划时,会将该SQL中涉及的子查询和视图,拆分为相应的查询块。分别为每一个查询块制定执计划。

其使用方法和注意事项,也与INDEX提示相同,为节省篇幅,这再不再赘述。

下面,我们通过实验来说明施加该提示时,优化器是如何使用索引的。

测试验证

首先,我们创建一个测试表,并在表的OWNER和OBJECT_ID列上,创建索引:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_index_ss_desc_05

如上图所示,我们创建了一个名为testtab的表,并在其上的owner和object_id列上创建了组合索引。

对目标表TESTTAB收集统计信息,并设置SQLPLUS下的环境参数,以便显示的内容方便查看。如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_倒序_06


Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_07


这里在会话级别上设置 statistics_level=all 是为了后面可以观察到使用正序和倒序方式进行索引跳扫时,所消耗的逻辑读的差异。发出以下查询:

select object_name,object_id,owner from testtab where object_id<10 order by object_id;

并查看此时的执行计划,如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_08

如上图所示,我们可以看到,由于只使用了OBJECT_ID列做过滤条件,而创建的索引是在OWNER和OBJECT_ID列上创建的,并没有使用到前导列上的过滤条件。因此,这种情况下,当前导列上的唯一值较少时,就会采用索引跳扫的方式来使用索引。

而提示INDEX_SS_ASC表示以正序的方式来访问索引,其行为与INDEX_SS的表现是相同的,即,INDEX_SS默认的行为,就是以正序的方式来访问索引。所谓正序访问,即在扫描索引的叶子块时,是从左至右(即从小到大)的方式来访问索引。而因为我们是在两个列上创建的组合索引,这里的“小”和“大”,是指先按前导列(在本例中,指OWNER列)排序,当前导列值相同时,再按后续列(在本例中,指OBJECT_ID列)来排序。

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_09


如上图所示,我们可以看到INDEX_SS_ASC提示的表现与INDEX_SS是相同的。而当使用INDEX_SS_DESC提示时,则表示以倒序的方式来访问索引。即在扫描索引的叶子块时,是从右至左(即从大到小)的方式来访问索引。其执行计划是如下:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_10

在一些特定情况下,当我们需要访问的记录,位于索引更靠右侧的叶子块中时,使用INDEX_SS_DESC的提示,将能更快地找到期望的结果,从而用更少的开销来执行。
比如下面的这条SQL:
select object_name,object_id,owner from testtab where object_id<10 and rownum<=2 order by object_id;

其目的是从表中找出OBJECT_ID列中值小于10的记录,并且,只返回其中的2行即可。

在我们创建的示例表TESTTAB中,OBJECT_ID列中值小于10的记录所对应的OWNER列中的值,均为SYS。如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_hint_11

而OWNER列中,总共有35个不同的值,其中SYS值位于比较靠后的位置,如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_倒序_12


因此,对应的object_id<10的记录,也会出现在索引中更靠后(即更靠右)的位置。在这种情形下,如果是按从小到大的方式来扫描索引,会扫描到比较靠后的索引叶子块时,才能找到满足object_id<10的记录。而如果是按从大到小的方式来扫描索引,其只需要扫描相对较少的索引叶子块,就可以找到满足条件的记录。

测试过程如下:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_index_ss_13


如上图所示,我们可以看到,当使用正序方式进行索引跳扫时,需要访问13个索引块,才能找够2行满足条件的记录。

而如果我们使用倒序的方式进行索引跳扫,则需要访问的索引块要少得多,只需要扫描7个索引块就可以了。如下图所示:

Oracle Hint(提示)之INDEX_SS、INDEX_SS_ASC、INDEX_SS_DESC_index_ss_desc_14

知识总结

1、index_ss提示用于指导优化器,通过索引跳跃扫描的方式来访问目标索引。
2、index_ss与index_ss_asc均表示用正序的方式来访问索引,即在扫描索引的叶子块时,是从左至右(即从小到大)的方式来访问索引。而index_ss_desc提示,则表示使用倒序的方式访问索引,即在扫描索引的叶子块时,是从右至左(即从大到小)的方式来访问索引。
3、索引跳扫只会发生在组合索引上,且SQL中,并没有指定索引前导列的过滤条件。

参考文档

《Oracle® Database SQL Language Reference》

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月30日 0

暂无评论

IE5LYMWlmdvL
最新推荐 更多

2024-05-17