新增分区+导入统计信息导致的问题

最近出了一个问题,由于新增分区后,导入了表上一个分区的统计信息做为新分区的统计信息,一条SQL走错了。类似如下的查询select * from a where b=1 and c>sysdate-7。由于c列是个日期型。导入的统计信息记录的最大值比当前日期小了快一个月,因此ORACLE评估出来的sysdate-7的数据量就特别小。因此导致本该走b列的索引走了c列。

如下方式,可以把拷贝统计信息,修改列的最大值最小值都一起实现。本例中只是修改了一个列的最大值最小值。

DECLARE
  srec      DBMS_STATS.STATREC;
  v_distcnt NUMBER;
  v_density NUMBER;
  v_nullcnt NUMBER;
  v_avgclen NUMBER;
  datevals  DBMS_STATS.DATEARRAY;
begin
  dbms_stats.copy_table_stats(ownname     => 'EVE',-----------------------拷贝统计信息
                              tabname     => 'sss',
                              srcpartname => 'P201111',
                              dstpartname => 'SYS_P310');
  DBMS_STATS.get_column_stats(ownname  => 'EVE',--------------------------获得字段的统计信息
                              tabname  => 'sss',
                              partname => 'P201111',
                              colname  => 'GMT_CREATED',
                              distcnt  => v_distcnt,
                              density  => v_density,
                              nullcnt  => v_nullcnt,
                              srec     => srec,
                              avgclen  => v_avgclen);
  datevals := DBMS_STATS.datearray(to_date('2011-01-01', 'yyyy-mm-dd'),--------------最大值,最小值
                                   to_date('2011-01-01', 'yyyy-mm-dd'));
  dbms_stats.prepare_column_values(srec, datevals);
  DBMS_STATS.set_column_stats(ownname  => 'EVE',-------------------------修改字段的统计信息,包括最大值
                              tabname  => 'sss',
                              partname => 'SYS_P310',
                              colname  => 'GMT_CREATED',
                              distcnt  => v_distcnt,
                              density  => v_density,
                              nullcnt  => v_nullcnt,
                              srec     => srec,
                              avgclen  => v_avgclen);

  COMMIT;
END;
/

请使用浏览器的分享功能分享到微信等