分区列上的绑定变量与排序的一点关系

    大量的排序操作会占用大量的CPU资源, 即便是内存中的排序. 通常我们可以用索引来 避免排, 但在分区表上, 就有些区别了. 下面是我做的一个测试例子, 你会知道在分区列上使用绑定变量 时会引起不必要的排序. 虽然在这个例子中用不用绑定变量都很明显地只访问一个分区, 但是Oracle还是 在用绑定变量时进行了不必要的排序. 因此Oracle有时是笨得可爱.

    请使用下面的角本来创建测试表:

CREATE TABLE TEST_SORT
(
  COL1 NUMBER,
  COL2 NUMBER,
  pkey number,
  col3 varchar2(30)
)
partition by range(pkey)
(
  partition p0 values less than (1),
  partition p1 values less than (2),
  partition p2 values less than (3)
) tablespace data02;

INSERT INTO TEST_SORT
  SELECT ROWNUM, MOD(ROWNUM,100), mod(rownum,3), OBJECT_NAME
    FROM DBA_OBJECTS WHERE ROWNUM < 5001;

commit;
CREATE INDEX IDX_TEST_SORT ON (COL1,COL2,PKEY) LOCAL;

    然后检查用和不用绑定变量的两个SQL的执行计划:

SELECT * FROM TEST_SORT
    WHERE COL2=:p_co1 AND PKEY=0 AND COL1 IN (810,510,210)
    ORDER BY COL1;

Execution Plan
----------------------------------------------------------
  0      SELECT STATEMENT Optimizer=RULE (Cost=3 ...
  1    0  INLIST ITERATOR
  2    1    TABLE ACCESS (BY LOCAL INDEX ROWID) OF ...
  3    2      INDEX (RANGE SCAN) OF 'TEST_SORT_IDX1'

SELECT * FROM TEST_SORT
    WHERE COL2=:p_co1 AND PKEY=:P_KEY AND COL1 IN (810,510,210)
    ORDER BY COL1;

Execution Plan
----------------------------------------------------------
  0      SELECT STATEMENT Optimizer=RULE (Cost=3 ...)
  1    0  SORT (ORDER BY) (Cost=3 Card=1 Bytes=31)
  2    1    PARTITION RANGE (SINGLE)
  3    2      INLIST ITERATOR
  4    3        TABLE ACCESS (BY LOCAL INDEX ROWID) OF ...
  5    4          INDEX (RANGE SCAN) OF 'TEST_SORT_IDX1'

    你可以使用10046事件获得执行时的更详细的区别.

留言 (1)

索引建在(col1,col2,pkey)上面, 是LOCAL的.

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • Please check the date.
  • 请核实一下日期.
  • What were you doing this time last year?
  • 去年这时候你在干什么?
  • How long will the sale last?
  • 折价销售多久?
  • Only three days.
  • 仅三天.
  • I'll be back in 5 days.
  • 我五天之后回来.