最近出了一个问题,由于新增分区后,导入了表上一个分区的统计信息做为新分区的统计信息,一条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;
/