注册
大数据量时快速收集统计信息方法
专栏/技术分享/ 文章详情 /

大数据量时快速收集统计信息方法

### 2026/09/30 153 0 0
摘要

当全库数据量较大时,按模式更新统计信息比较慢,可以使用全列收集统计信息的方式进行收集,通过存储过程完成对全库全部列的收集:
STAT < 统计信息采样百分比 > ON [< 模式名 >.]< 表名 >(< 列名 >);
如:STAT 100 ON TEST(A);

--更新指定表的所有列的统计信息可使用 SYSDBA 或者用户自身
--DROP TABLE SYSDBA.stat_history;
--SELECT * FROM SYSDBA.stat_history;
--创建日志记录表
create table SYSDBA.stat_history (beg_time TIMESTAMP,end_time timestamp,sql_str varchar2(500),table_name varchar2(200),col_name VARCHAR2(200));

--创建存储过程
CREATE OR REPLACE PROCEDURE "SYSDBA"."TABLE_STATS"
AUTHID DEFINER
AS
	declare --更新所有列的统计信息
v_sql varchar(4000);
v_begtime VARCHAR2(200);
v_endtime varchar2(200);
CURSOR c1 IS SELECT
  SCH.NAME AS SCHEMA_NAME,
        TAB.NAME AS TABLE_NAME ,
        SYSCOL.NAME AS COLUMN_NAME
FROM
        SYSOBJECTS AS TAB,
        SYSOBJECTS AS SCH,
        SYSCOLUMNS AS SYSCOL
WHERE
        SCH.ID =TAB.SCHID
    AND TAB.ID =SYSCOL.ID
    AND SCH.NAME in ('SYSDBA')   --填写实际用户名
    AND SYSCOL.TYPE$ NOT IN ('BLOB','CLOB','TEXT')
    and TAB.NAME  IN(select  TABLE_NAME  from ALL_TABLES WHERE OWNER in ('SYSDBA') and TABLE_NAME not like '%BM$_%' AND TABLE_NAME NOT LIKE 'MTAB$%');  
begin
  execute immediate 'truncate table SYSDBA.STAT_HISTORY;';
  for i in c1 
  loop  
  v_sql='stat 100 on '||i.SCHEMA_NAME||'."'||i.TABLE_NAME||'"("'||i.COLUMN_NAME||'");';
  begin  
  v_begtime := sysdate();  
  execute immediate v_sql;
  v_endtime := sysdate();
  insert into SYSDBA.stat_history VALUES (v_begtime,v_endtime,v_sql,i.TABLE_NAME,i.COLUMN_NAME);
  commit;
     EXCEPTION WHEN OTHERS THEN
                PRINT SQLERRM;  
  end;
  end loop; 
  end;   
--调用存储过程
call "SYSDBA"."TABLE_STATS" ();

select * from SYSDBA.stat_history;

注意:使用“STAT 100 on 表名(列名)”的方法收集统计信息时,水平分区表子表采样数受 HP_STAT_SAMPLE_COUNT 参数影响。需要适当调大此参数,参数值大于实际分区数,否则分区表统计信息收集不准确,参数修改方法如下:

sp_set_para_value(1,'HP_STAT_SAMPLE_COUNT',2000);
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服