« 你用过Oracle的Global Partition Index吗? »
Oracle » http://www.anysql.net/oracle/oracleglobal_partition_index.html 2007-01-31Oracle的分区表也不是十分好用, 当分区的数目比较多时, 很可能让一些不能进行Partition Prune的SQL拥有很高的逻辑读(Consistent Gets), 解决的办法是将一些索引建成全局索引. 现在我们来看一下相反的例子, Oracle中的表是不分区的, 而且访问量最多的SQL是根据一个选择性很好的索引去走的, 每次执行的逻辑读也就只有4-6个了, 因为访问量很高, 如果能降底一个逻辑读的话, 也可能降底整个系统5%-10%的逻辑读, 我们应当从哪儿来考虑呢? 索引的层次(Level)绝对是一个值得研究的角度. 事实上如果我们能让索引的层次(Level)高度降一级, 就可以降低一个逻辑读了, 通过常有以下的方法可用:
1, Rebuild索引.2, 删除一部份数据后重建索引.3, 将索引建到一个较大Block Size的表空间中.4, 建成Global Partitioned索引.
什么是Global Partitioned索引? 指的是在非分区表上建的分区索引, 或者是分区表上但分区方法和表不相同的索引. 通过分区技术, 我们可以将一个大的索引划分为小片, 从而降底索引的层次(Level). 下面来看一下如何在非分区表上建分区索引:
create table t_objects as select * from all_objects;
create index t_objects_id_idx on t_objects (object_id)
global partition by hash(object_id) partitions 4;
虽然表是非分区表, 但有了这样一个分区的索引后, 所有这个表的SQL都将采用CBO, 这是需要考虑的地方, 取决你的SQL现在运行的方式.


有价值,记下了.
原来只知道降低Level会有帮助, 没想到Partiton Index 有这个好处. 马上Benchmark RunStats + SQL Auto Trace 测试一下.
这下有了具体执行方法了.
另外, 恭喜你当爸爸了.
我老婆还不愿意生哩.
居然要到10g才支持这种用法.
理论上好像如此,但实际应用中,Global Partitioned索引在性能上好像比普通global index还要差,我测试了好几遍都是这样,不知有没有经过测试?
说说你的测试方案?多少的数据量,分析一下索引,看一下索引的层次有没有降低。
我建了两个相同数量级的表,10万 100万 1000万都测试了。
然后分别在上面建global partition index和 普通index
然后根据索引查询相同的数据,发现global partition index的逻辑读更高
10万 100万 1000万级都测了,新建global partiton index 和普通index索引测试的
你的性能数据呢?
SQL> create index ind_glb_id on part_t1(object_id);
Index created.
Elapsed: 00:00:00.55
SQL> set autotrace traceonly
SQL> select * from part_t1 where object_id=30000;
Elapsed: 00:00:00.02
Execution Plan
————————————————
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=2 Card=41 Bytes=
3239)
1 0 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF ‘PART_T1′ (Cost=2
Card=41 Bytes=3239)
2 1 INDEX (RANGE SCAN) OF ‘IND_GLB_ID’ (NON-UNIQUE) (Cost=1
Card=16)
Statistics
—————–
110 recursive calls
0 db block gets
21 consistent gets
1 physical reads
1 rows processed
SQL> create index idx_glb_p1 on part_t1(object_id) global partition by range (object_id) (partition p1 values less than (20000),partition p2 values less than (MAXVALUE));
Index created.
Elapsed: 00:00:00.38
SQL>
SQL> set autotrace traceonly
SQL> select * from part_t1 where object_id=30000;
Elapsed: 00:00:00.05
Execution Plan
———————————–
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=2 Card=41 Bytes=
3239)
1 0 TABLE ACCESS (BY GLOBAL INDEX ROWID) OF ‘PART_T1′ (Cost=2
Card=41 Bytes=3239)
2 1 INDEX (RANGE SCAN) OF ‘IDX_GLB_P1′ (NON-UNIQUE) (Cost=1
Card=16)
Statistics
———————————————
1081 recursive calls
0 db block gets
263 consistent gets
1 physical reads
30 sorts (memory)
0 sorts (disk)
1 rows processed
不要运行一次就决定SQL的执行成本高低。
运行多次也是如此,最好的情况是一样的,体现不出性能上的优势,千万级的表我也试过。当然管理上是有比较好的优势