Oracle CBO认为Cost为0

    在一个分区表上去执行一个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

我一般用dbms_stats中的set包,根据其他分区的统计信息,给空分区写入一些假的统计信息,来保证执行计划稳定~

发表留言:

« Previous | Main | Next »

英语900句 | English 900

  • You may go in now.
  • 您可以进去了.
  • Nice to see you, my old friend.
  • 真高兴见到你, 我的老朋友.
  • How have you been these years?
  • 这些年你怎么样?
  • You've changed little.
  • 你一点也没变.
  • Do you still remember that Christmas?
  • 你仍记得那个圣诞节吗?