在一个分区表上去执行一个SQL时(在Where条件中用了分区列等于的条件, 分区列为主键索引的最后一列), 发现用错了执行计划, Oracle居然认为某个SQL的执行计划的成本为0, 实际上是肯定没有本为0的执行计划的, 因此是明显的不合理的现象.
SQLPLAN COST CARD KBYTE PS PE
------------------------------------------------ ---- ---- ----- -- --
0 SELECT STATEMENT Optimizer=RULE 0 1 0
1 0 SORT (GROUP BY) 1 0
2 1 PARTITION RANGE (SINGLE) 0 1 0 3 3
3 2 TABLE ACCESS (BY LOCAL INDEX ROWID 0 1 0 3 3
4 3 INDEX (SKIP SCAN) OF TEST_TAB_PK 0 1 3 3
产生的原因是因为分区的统计信息是过时的, 执行分析时这个分区还没有任何记录, 就产生了这个问题.
ASQL> SELECT PARTITION_NAME, BLEVEL,LEAF_BLOCKS,
2 DISTINCT_KEYS,NUM_ROWS
3 FROM DBA_IND_PARTITIONS
4 WHERE INDEX_NAME='TEST_TAB_PK';
PARTITION_NAME BLEVEL LEAF_BLOCKS DISTINCT_KEYS NUM_ROWS
---------------- ------ ----------- ------------- --------
TEST_TAB_PK_P06 0 0 0 0
TEST_TAB_PK_P07 3 364320 73835520 73835520
TEST_TAB_PK_P08 0 0 0 0
TEST_TAB_PK_P09 0 0 0 0
TEST_TAB_PK_P10 0 0 0 0
TEST_TAB_PK_PMAX 0 0 0 0
但很显然Oracle这样算是不合理的, 谁能天天去分析表呢, 又有谁敢呢? 最好是当统计值为0时, 当作默认值来处理, 在另一个没有分析过的数据库上就是好的. 现在最好的做法, 就是分析后, 将空的分区上的统计信息删除, 当然可以用程序来做到这一点.
在7x24小时的OLTP系统中, 分区是要用的, 出了问题是严重的, 你有什么高见?
留言 (2)
hehe,以前也碰到了这个问题,系统运行一段时间,跨越分区之后执行计划就变了,很头疼,最后干脆用hint
Posted by brotherxiao | Mar 11, 2008 10:34 AM
我一般用dbms_stats中的set包,根据其他分区的统计信息,给空分区写入一些假的统计信息,来保证执行计划稳定~
Posted by BMC | Apr 11, 2008 9:47 AM