建测试表: drop table SCOTT.TB_TEST01; create table SCOTT.TB_TEST01 partition by range (CREATED) ( partition P_2015 values less than (TO_DATE(" 2016-01-01 00:00:00", "SYYYY-MM-DD HH24:MI:SS")), partition P_2016 values less than (TO_DATE(" 2017-01-01 00:00:00", "SYYYY-MM-DD HH24:MI:SS")), partition P_MAX values less than (MAXVALUE) ) as select * from dba_objects; ##插入测试数据 insert into SCOTT.TB_TEST01 select * from SCOTT.TB_TEST01; commit; insert into SCOTT.TB_TEST01 select * from SCOTT.TB_TEST01; commit; insert into SCOTT.TB_TEST01 select * from SCOTT.TB_TEST01; commit; insert into SCOTT.TB_TEST01 select * from SCOTT.TB_TEST01; commit;
#修改测试数据使其均匀分布 alter table SCOTT.TB_TEST01 enable row movement;
update SCOTT.TB_TEST01 set created=to_date("20150101","yyyymmdd")+dbms_random.value(1,1000); commit;
#收集一下统计信息 begin dbms_stats.gather_table_stats(ownname=>"scott",tabname => "TB_TEST01", cascade=> TRUE ); end;
情况1:过滤条件在全分区 查询语句: select * from SCOTT.TB_TEST01 where owner="SCOTT" and object_type="TABLE";
#建普通索引 create index scott.idx_TB_TEST01 on SCOTT.TB_TEST01(owner,object_type); #执行计划 Execution Plan ---------------------------------------------------------- Plan hash value: 2208186213
Predicate Information (identified by operation id): ---------------------------------------------------
3 - access("OWNER"="SCOTT" AND "OBJECT_TYPE"="TABLE")
#统计信息 Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 147 consistent gets 0 physical reads 0 redo size 11678 bytes sent via SQL*Net to client 644 bytes received via SQL*Net from client 13 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 176 rows processed
#上面的测试cost=23,consistent gets=147 小结: 1.从上面测试可以看出,本地分区索引成本大于普通索引.因为此时用本地分区索引是需要PARTITION RANGE ALL的. 2.查询语句中的两个过滤条件都是等值的,在建这种复合索引时,索引列的顺序跟成本没有关系.这里没有测试,有兴趣可以测试。
情况2:过滤条件在单分区 查询语句: select * from SCOTT.TB_TEST01 where owner="SCOTT" and object_type="TABLE" and created between to_date("20161230","yyyymmdd") and to_date("20160105","yyyymmdd");
#建一个差的索引 drop index scott.idx_TB_TEST01; create index scott.idx_TB_TEST01 on SCOTT.TB_TEST01(created,owner,object_type);
SQL> select * from SCOTT.TB_TEST01 where owner="SCOTT" and object_type="TABLE" and created between to_date("20161230","yyyymmdd") and to_date("20160105","yyyymmdd");
#执行计划 Execution Plan ---------------------------------------------------------- Plan hash value: 783220382
Predicate Information (identified by operation id): ---------------------------------------------------
3 - access("OWNER"="SCOTT" AND "OBJECT_TYPE"="TABLE" AND "CREATED">=TO_DATE(" 2016-06-11 00:00:00",
"syyyy-mm-dd hh24:mi:ss") AND "CREATED"<=TO_DATE(" 2016-07-11 00:0 0:00", "syyyy-mm-dd hh24:mi:ss"))
#统计信息 Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 8 consistent gets 0 physical reads 0 redo size 1872 bytes sent via SQL*Net to client 523 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 4 rows processed
#上面的测试cost=11,consistent gets=8
小结: 1.建的第一个差索引,之所以差,是因为created字段是一个区间值,此时access只能对应created字段,而owner字段和object_type都是通过filter过滤的.所以过滤条件是区间和要放后面. 2.从上面测试可以看出,本地分区索引成本小于普通索引.此时本地分区索引使用PARTITION RANGE SINGLE.
情况3:过滤条件在跨分区 查询语句: select * from SCOTT.TB_TEST01 where owner="SCOTT" and object_type="TABLE" and created between to_date("20161220","yyyymmdd") and to_date("20170205","yyyymmdd");
#建普通索引 drop index scott.idx_TB_TEST01; create index scott.idx_TB_TEST01 on SCOTT.TB_TEST01(owner,object_type,created);
SQL> select * from SCOTT.TB_TEST01 where owner="SCOTT" and object_type="TABLE" and created between to_date("20161220","yyyymmdd") and to_date("20170205","yyyymmdd");
#执行计划 Execution Plan ---------------------------------------------------------- Plan hash value: 2208186213