执行计划使用 B+ 树索引,而且还排序

Joh*_*Fr. 5 oracle-11g sqlplus execution-plan sorting explain

我正在使用 Oracle sqlplus。我有以下查询:

SELECT fooID from foo MINUS
SELECT fooID from bar;
Run Code Online (Sandbox Code Playgroud)

我创建了两个非聚集 B+ 树索引。一个在fooID表的字段中foo,一个在表的字段fooIDbar。之后,我分析了两个表的统计信息:foobar使用EXPLAIN PLAN .... 但我明白了:

  SELECT STATEMENT
      MINUS
        SORT UNIQUE
          INDEX FAST FULL SCAN FOO_INDEX
        SORT UNIQUE
          INDEX FAST FULL SCAN BAR_INDEX
Run Code Online (Sandbox Code Playgroud)

这怎么可能呢?做的时候INDEX FAST FULL SCAN,因为索引是 B+ 树,系统不会取回它的元组排序吗?为什么需要这样做SORT UNIQUE(数据已经排序)?

Ren*_*ger 4

Oracle 关于全索引扫描下的索引和索引组织表的说法:在全索引扫描中,数据库按顺序读取整个索引。

然而,在Fast Full Index Scan下,它写道: 快速全索引扫描是数据库访问索引本身中的数据而不访问表的全索引扫描,并且数据库以不特定的顺序读取索引块。(强调我的)

现在,问题可能应该是:为什么优化者选择INDEX FAST FULL SCANINDEX FULL SCAN.

后一个问题的答案给出了提示11.2.3.7快速全索引扫描:快速全扫描比普通全索引扫描更快,因为它可以使用多块 I/O,并且可以像表扫描一样并行运行。

如果您坚持 Oracle 使用完整索引扫描,您可能想尝试一下/*+ index() */提示:

create table tq84_foo (
  fooID number not null
);

create table tq84_bar (
  fooID number not null
);

create unique index ix_foo on tq84_foo(fooID);
create unique index ix_bar on tq84_bar(fooID);

explain plan for
 select /*+ index(f ix_foo) */fooID from tq84_foo f
        MINUS
select /*+ index(b ix_bar) */ fooID from tq84_bar b;

select * from table(dbms_xplan.display);
Run Code Online (Sandbox Code Playgroud)

导致

------------------------------------------------------------------------------
| Id  | Operation           | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |        |     1 |    26 |     4  (75)| 00:00:01 |
|   1 |  MINUS              |        |       |       |            |          |
|   2 |   SORT UNIQUE NOSORT|        |     1 |    13 |     2  (50)| 00:00:01 |
|   3 |    INDEX FULL SCAN  | IX_FOO |     1 |    13 |     1   (0)| 00:00:01 |
|   4 |   SORT UNIQUE NOSORT|        |     1 |    13 |     2  (50)| 00:00:01 |
|   5 |    INDEX FULL SCAN  | IX_BAR |     1 |    13 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)