大量的排序操作会占用大量的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的.
Posted by anysql | Aug 21, 2006 11:21 AM