Oracle 统计信息备份/表分析
众所周知,统计信息直接影响到Oracle优化器最后的执行计划,所以定期收集统计信息成为DBA一项常规的工作,但是,对于一些大表,比如数据量超过几千万条,表分析后却有可能会导致应用系统一些SQL执行计划变差,比如出现大量的全表扫,严重影响数据库性能.如果出现这种情况,一种方法是对找一张该查询涉及到的小表,执行grant select on table_name to public操作,然后再看执行计划是否变好,有时可能这个动作要尝试多次.如果实在不行,只有导回原先的统计信息。这就需要分析之前对统计信息作过备份。下面阐述备份的操作:
conn perfstat/perfstat
创建统计信息的备份表:
exec dbms_stats.CREATE_STAT_TABLE(OWNNAME=>'PERFSTAT',STATTAB=>'BK_STAT_200809',TBLSPACE=>'TOOLS');
表的owner为perfstat,这张存放统计信息的表名为:bk_stat_200809,表空间为perfstat的默认表空间tools。
为这张表创建一个同义词,方便其它用户访问:
create public synonym BK_STAT_200809 for BK_STAT_200809;
赋予perfstat权限,否则无法备份统计信息:
conn /as sysdba
grant analyze any to perfstat;
生成备份需要分析的表的统计信息的SQL,条件因需求不同而不同,我这里是锁定某几个用户下面08年1月前分析过的表。
conn perfstat/perfstat
set line 250
set pages 10000
set timing on
set time on
col script_for_export_stat for a250
spool script_for_export_stat.sql
select 'exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>' || '''' ||
upper(owner) || ''',statown=>''PERFSTAT'',TABNAME=>' || '''' || upper(table_name) ||
''',STATTAB=>''BK_STAT_200809'',STATID=>''BK_STAT_20080918'');' as script_for_export_stat
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and last_analyzed < to_date('20080101', 'yyyymmdd')
order by owner;
spool off
这样,生成如下面的SQL:
exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>'MOCSACCT',statown=>'PERFSTAT',TABNA
ME=>'TPAYORDER',STATTAB=>'BK_STAT_200809',STATID=>'BK_STAT_20080918');
exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>'MOCSACCT',statown=>'PERFSTAT',TABNA
ME=>'T_ACCTWATER',STATTAB=>'BK_STAT_200809',STATID=>'BK_STAT_20080918');
exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>'MOCSACCT',statown=>'PERFSTAT',TABNA
ME=>'T_BALANCELOG',STATTAB=>'BK_STAT_200809',STATID=>'BK_STAT_20080918');
exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>'MOCSACCT',statown=>'PERFSTAT',TABNA
ME=>'T_DEDUCTIONINFO',STATTAB=>'BK_STAT_200809',STATID=>'BK_STAT_20080918');
exec dbms_stats.EXPORT_TABLE_STATS(OWNNAME=>'MOCSACCT',statown=>'PERFSTAT',TABNA
ME=>'T_BOSSUSERSTATUSNOTIFY',STATTAB=>'BK_STAT_200809',STATID=>'BK_STAT_20080918
');
另外,可以查看一下需要分析的表的大小:
select a.owner,a.segment_name,a.segment_type,a.tablespace_name,round(a.bytes/1024/1024/1024,2) tablesize,b.last_analyzed
from dba_segments a,dba_tables b
where a.segment_name=b.table_name
and b.owner in ('MOCSACCT','MOCSCARD')
and b.last_analyzed < to_date('20080101', 'yyyymmdd');
分析表的方法可用analyze语句进行分析,也可用dbms_stats包进行分析。Oracle 9i开始就推荐使用dbms_stats包进行分析,且analyze语句对于分区表的支持不是很好:用analyze语句分析后,查询dba_tables.last_analyed信息会不准确,但是dba_part_tables. last_analyed信息是准确的,存在这个bug。因此,在分析时,推荐使用dbms_stats包来进行分析。―――小荷语
根据不表的不同大小,执行不同的采样值
小于500M的表,estimate_percent按100%分析,大于500M小于1G的表,按50%分析;大于1G小于5G的表,按10%分析;大于5G小于10G的表,按3%分析;大于10G的表小于20G的表按1%分析;大于20G的表不建议轻易分析,当然,这也与每个项目及系统的特点有关。
可以用以下的语句直接生成分析语句:
set line 250
col script_for_gather_stat for a250
spool script_for_gather_stat.sql
select 'exec dbms_stats.gather_table_stats(OWNNAME=>'||''''||upper(owner)||''',tabname=>'||''''||
upper(table_name)||''',cascade=>TRUE);' as script_for_gather_stat
from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m<=500
union all
select 'exec dbms_stats.gather_table_stats(OWNNAME=>'||''''||upper(owner)||''',tabname=>'||''''||
upper(table_name)||''',cascade=>TRUE,estimate_percent=> 50);' as script_for_gather_stat
from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m between 500 and 1024
union all
select 'exec dbms_stats.gather_table_stats(OWNNAME=>'||''''||upper(owner)||''',tabname=>'||''''||
upper(table_name)||''',cascade=>TRUE,estimate_percent=> 10);' as script_for_gather_stat
from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m between 1024 and 5120
union all
select 'exec dbms_stats.gather_table_stats(OWNNAME=>'||''''||upper(owner)||''',tabname=>'||''''||
upper(table_name)||''',cascade=>TRUE,estimate_percent=> 3);' as script_for_gather_stat
from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m between 5120 and 10240
union all
select 'exec dbms_stats.gather_table_stats(OWNNAME=>'||''''||upper(owner)||''',tabname=>'||''''||
upper(table_name)||''',cascade=>TRUE,estimate_percent=> 1);' as script_for_gather_stat
from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m between 10240 and 20480
union all
select '--NOT ANALYZE TABLE LAGER THAN 20G:'||table_name from (
select owner,segment_name table_name, sum(bytes) / 1024 / 1024 size_m
from dba_segments
where owner in ('MOCSCARD','MOCSACCT')
and segment_name in
(select table_name
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in
('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd'))
group by segment_name,owner
order by size_m) a
where a.size_m>20480
执行后我得到下列结果:
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSCARD',tabname=>'T_CARDCODE',cascade=>TRUE);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'SERVICEINFO',cascade=>TRUE);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSCARD',tabname=>'SERVICEINFO',cascade=>TRUE);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'TPAYAPPINFO',cascade=>TRUE);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'T_USERACCT',cascade=>TRUE,estimate_percent=> 10);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'T_ACCTINFO',cascade=>TRUE,estimate_percent=> 10);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'T_ACCTBOOK',cascade=>TRUE,estimate_percent=> 10);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSCARD',tabname=>'T_CARDWATER',cascade=>TRUE,estimate_percent=> 10);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSCARD',tabname=>'T_CARDINFO',cascade=>TRUE,estimate_percent=> 10);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'T_ACCTINFO_HIS',cascade=>TRUE,estimate_percent=> 3);
exec dbms_stats.gather_table_stats(OWNNAME=>'MOCSACCT',tabname=>'T_TEMP_ACCTWATER',cascade=>TRUE,estimate_percent=> 3);
现在,就可以执行以上的分析语句进行分析了,建议在系统空闲的时候进行分析用crontab定时任务完成。
一旦发生意外,则可以导回原来的统计信息!
col script_for_import_stat for a250
spool script_for_import_stat.sql
select 'exec dbms_stats.IMPORT_TABLE_STATS(OWNNAME=>' || '''' ||
upper(owner) || ''',statown=>''PERFSTAT'',TABNAME=>' || '''' || upper(table_name) ||
''',STATTAB=>''BK_STAT_200809'',STATID=>''BK_STAT_20080918'');' as script_for_import_stat
from dba_tables
where last_analyzed is not null
and owner in ('MOCSCARD','MOCSACCT')
and table_name not in ('SUBSCRIPTION_HISTORY', 'SUBSCRIBER_HISTORY')
and last_analyzed < to_date('20080101', 'yyyymmdd');
spool off
Oracle 统计信息备份/表分析相关推荐
- oracle 统计信息字典表,Oracle数据字典表查询
/*显示当前用户*/ show user 在sql plus中可用,在pl sql中不可用 /*查看所有用户名*/selectusername,user_id,createdfromall_users ...
- [Oracle] oracle统计信息
Oracle统计信息 Oracle数据库里的统计信息可以分为6种类型: 表的统计信息 索引的统计信息 列的统计信息 系统统计信息 数据字典统计信息 内部对象统计信息 图 1: Oracle统计信息 基 ...
- Oracle统计信息的导出、导入
http://oracle.chinaitlab.com/induction/791615.html 1 创建一个专用表保存各表的统计信息: exec dbms_stats.create_stat_t ...
- oracle收集统计信息和直方图,oracle统计信息和直方图
oracle统计信息和直方图的理解[@more@]以前一直对统计信息的理解就是对行的数据分布的,提供改CBO来选择高效的执行计划.这段时间看了不少资料,对统计有了一个更清晰的认识 统计信息: 1,表中 ...
- oracle数据库直方图,[转] oracle统计信息(statistics)和直方图(histogram)
oracle统计信息和直方图的理解 以前一直对统计信息的理解就是对行的数据分布的,提供改CBO来选择高效的执行计划.这段时间看了不少资料,对统计有了一个更清晰的认识 统计信息: 1,表中的统计信息 2 ...
- 详解Oracle统计信息
优化器统计范围: 表统计: --行数,块数,行平均长度:all_tables:NUM_ROWS,BLOCKS,AVG_ROW_LEN: 列统计: --列中唯一值的数量(NDV),NULL值的数量,数据 ...
- 收集oracle统计信息
原文地址为: 收集oracle统计信息 优化器统计范围: 表统计: --行数,块数,行平均长度:all_tables:NUM_ROWS,BLOCKS,AVG_ROW_LEN: 列统计: --列中唯一值 ...
- oracle统计信息被锁定处理
oracle统计信息被锁定处理 基本现象 ORA-20005: object statistics are locked (stattype = ALL) 在进行SQL时,发现一个表的统计信息过旧,想 ...
- oracle 查看索引大小_技术分享|简述Oracle统计信息
于树文 云技术管理处 在Oracle的11g版本中,统计信息为自动收集功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能).有时候在生产环境中, ...
最新文章
- mysql zrm 配置_利用MySQL-zrm来备份和恢复MySQL数据库方法详解
- 99%创业会失败 去中心化是良药么?
- POS消费机C#例子代码
- 一种table超出高度自动出滚动条的解决方案
- 利用Facebook提供的免费工具进行宣传
- java strlen,跟妹妹聊到 Java 16 新特征,真香!
- 微信JS图片上传与下载功能--微信JS系列文章(三)
- 中国急性髓系白血病药物市场趋势报告、技术动态创新及市场预测
- 目录_计算机视觉——算法及应用
- virtuozo空三加密_VirtuoZoAAT空三加密中的应用技巧
- C语言中如何使用system函数
- Android Window/Window Z-Order/Surface/SurfaceView
- linux 如何加密文件夹,如何加密个别文件夹?
- Vue和Element第一天
- 其他人的爱情 VS 程序员的爱情
- QCC---Host configure tools
- 机器学习——EM算法
- JavaScript边学边玩的小游戏、好用的js网站:
- Retrying connect to server: xxx.xxx.xxx.xxx:8032. Already tried 0 time(s)
- UI设计教程分享:关于海报的合成过程
热门文章
- win7一直显示正在启动_win7系统中提高启动速度并且禁用某些软件启动的操作小技巧...
- 市面上有哪几种门_选择 low-e门窗玻璃,你想知道的都在这了
- roslyn分析字符串代码_.NET 5 源代码生成器——MediatR——CQRS
- jq父级绑定事件的意义_用jQuery.delegate()将事件绑定在父元素上面
- fcm 服务器接入 golang_Golang 写的即时通讯服务器 im(服务组件形式)
- java9 反应编程_Java9第四篇-Reactive Stream API响应式编程
- C语言小游戏 ——推箱子
- 使用计算机绘制景物图像的两个主要步骤是,计算机11考试.doc
- ctags 基本使用方法
- 关于PyTorch中的register_forward_hook()函数未能执行其中hook函数的问题