ORACLE 性能调整Word文档格式.docx
《ORACLE 性能调整Word文档格式.docx》由会员分享,可在线阅读,更多相关《ORACLE 性能调整Word文档格式.docx(20页珍藏版)》请在冰豆网上搜索。
user_dump_dest'
ANDp2.name='
db_name'
ANDp.addr=s.paddrANDs.audsid=USERENV('
SESSIONID'
)最后,可以通过Tkprof来解析跟踪文件,如Tkprof原文件勘晡募?
sys=n[Q]怎么设置整个数据库系统跟踪[A]其实文档上的altersystemsetsql_trace=true是不成功的但是可以通过设置事件来完成这个工作,作用相等altersystemsetevents'
10046tracenamecontextforever,level1'
;
如果关闭跟踪,可以用如下语句altersystemsetevents'
10046tracenamecontextoff'
其中的level1与上面的8都是跟踪级别level1:
跟踪SQL语句,等于sql_trace=truelevel4:
包括变量的详细信息level8:
包括等待事件level12:
包括绑定变量与等待事件[Q]怎么样根据OS进程快速获得DB进程信息与正在执行的语句[A]有些时候,我们在OS上操作,象TOP之后我们得到的OS进程,怎么快速根据OS信息获得DB信息呢?
我们可以编写如下脚本:
$morewhoit.sh#!
/bin/shsqlplus/nologUser,estimate_percent=>
100,cascade=>
TRUE);
这是对命令与工具包的一些总结1.对于分区表,建议使用DBMS_STATS,而不是使用Analyze语句。
a)可以并行进行,对多个用户,多个Tableb)可以得到整个分区表的数据和单个分区的数据。
c)可以在不同级别上ComputeStatistics:
单个分区,子分区,全表,所有分区d)可以倒出统计信息e)可以用户自动收集统计信息2.DBMS_STATS的缺点a)不能ValidateStructureb)不能收集CHAINEDROWS,不能收集CLUSTERTABLE的信息,这两个仍旧需要使用Analyze语句。
c)DBMS_STATS默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True3.对于oracle9里面的ExternalTable,Analyze不能使用,只能使用DBMS_STATS来收集信息。
[Q]怎么样快速重整索引[A]通过rebuild语句,可以快速重整或移动索引到别的表空间rebuild有重建整个索引数的功能,可以在不删除原始索引的情况下改变索引的存储参数语法为alterindexindex_namerebuildtablespacets_namestorage(……);
如果要快速重建整个用户下的索引,可以用如下脚本,当然,需要根据你自己的情况做相应修改SQL>
setheadingoffSQL>
setfeedbackoffSQL>
spoold:
index.sqlSQL>
SELECT'
alterindex'
||index_name||'
rebuild'
||'
tablespaceINDEXESstorage(initial256Knext256Kpctincrease0);
FROMall_indexesWHERE(tablespace_name!
='
INDEXES'
ORnext_extent!
=(256*1024))ANDowner=USERSQL>
spooloff另外一个合并索引的语句是alterindexindex_namecoalesce,这个语句仅仅是合并索引中同一级的leafblock消耗不大,对于有些索引中存在大量空间浪费的情况下,有一些作用。
[Q]如何使用Hint提示[A]在select/delete/update后写/*+hint*/如select/*+index(TABLE_NAMEINDEX_NAME)*/col1...注意/*和+之间不能有空格如用hint指定使用某个索引select/*+index(cbotab)*/col1fromcbotab;
select/*+index(cbotabcbotab1)*/col1fromcbotab;
select/*+index(acbotab1)*/col1fromcbotaba;
其中TABLE_NAME是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名;
INDEX_NAME可以不必写,Oracle会根据统计值选一个索引;
如果索引名或表名写错了,那这个hint就会被忽略;
[Q]怎么样快速复制表或者是插入数据[A]快速复制表可以指定Nologging选项如:
Createtablet1nologgingasselect*fromt2;
快速插入数据可以指定append提示,但是需要注意noarchivelog模式下,默认用了append就是nologging模式的。
在archivelog下,需要把表设置程Nologging模式。
如insert/*+append*/intot1select*fromt2注意:
如果在9i环境中并设置了FORCELOGGING,则以上操作是无效的,并不会加快,当然,可以通过如下语句设置为NOFORCELOGGING。
Alterdatabasenoforcelogging;
是否开启了FORCELOGGING,可以用如下语句查看SQL>
selectforce_loggingfromv$database;
[Q]怎么避免使用特定索引[A]在很多时候,Oracle会错误的使用索引而导致效率的明显下降,我们可以使用一点点技巧而避免使用不该使用的索引,如:
表test,有字段a,b,c,d,在a,b,c上建立联合索引inx_a(a,b,c),在b上单独建立了一个索引Inx_b(b)。
在正常情况下,wherea=?
andb=?
andc=?
会用到索引inx_a,whereb=?
会用到索引inx_b但是,wherea=?
groupbyb会用到哪个索引呢?
在分析数据不正确(很长时间没有分析)或根本没有分析数据的情况下,oracle往往会使用索引inx_b。
通过执行计划的分析,这个索引的使用,将大大耗费查询时间。
当然,我们可以通过如下的技巧避免使用inx_b,而使用inx_a。
wherea=?
groupbyb||'
--如果b是字符wherea=?
groupbyb+0--如果b是数字通过这样简单的改变,往往可以是查询时间提交很多倍当然,我们也可以使用no_index提示,相信很多人没有用过,也是一个不错的方法:
select/*+no_index(t,inx_b)*/*fromtesttwherea=?
groupbyb[Q]Oracle什么时候会使用跳跃式索引扫描[A]这是9i的一个新特性跳跃式索引扫描(IndexSkipScan).例如表有索引index(a,b,c),当查询条件为whereb=?
的时候,可能会使用到索引index(a,b,c)如,执行计划中出现如下计划:
INDEX(SKIPSCAN)OF'
TEST_IDX'
(NON-UNIQUE)Oracle的优化器(这里指的是CBO)能对查询应用IndexSkipScans至少要有几个条件:
1优化器认为是合适的。
2索引中的前导列的唯一值的数量能满足一定的条件(如重复值很多)。
3优化器要知道前导列的值分布(通过分析/统计表得到)。
4合适的SQL语句等。
[Q]怎么样创建使用虚拟索引[A]可以使用nosegment选项,如createindexvirtual_index_nameontable_name(col_name)nosegment;
如果在哪个session需要测试虚拟索引,可以利用隐含参数来处理altersessionset"
_use_nosegment_indexes"
=true;
就可以利用explainplanforselect……来看虚拟索引的效果利用@$ORACLE_HOME/rdbms/admin/utlxpls查看执行计划最后,根据需要,我们可以删除虚拟索引,如普通索引一样dropindexvirtual_index_name;
注意:
虚拟索引并不是物理存在的,所以虚拟索引并不等同于物理索引,不要用自动跟踪去测试虚拟索引,因为那是实际执行的效果,是用不到虚拟索引的。
[Q]怎样监控无用的索引[A]Oracle9i以上,可以监控索引的使用情况,如果一段时间内没有使用的索引,一般就是无用的索引语法为:
开始监控:
alterindexindex_namemonitoringusage;
检查使用状态:
select*fromv$object_usage;
停止监控:
alterindexindex_namenomonitoringusage;
当然,如果想监控整个用户下的索引,可以采用如下的脚本:
setheadingoffsetechooffsetfeedbackoffsetpages10000spoolstart_index_monitor.sqlSELECT'
||owner||'
.'
||index_name||'
monitoringusage;
FROMdba_indexesWHEREowner=USER;
spooloffsetheadingonsetechoonsetfeedbackon------------------------------------------------setheadingoffsetechooffsetfeedbackoffsetpages10000spoolstop_index_monitor.sqlSELECT'
nomonitoringusage;
spooloffsetheadingonsetechoonsetfeedbackon[Q]怎么样能固定我的执行计划[A]可以使用OUTLINE来固定SQL语句的执行计划用如下语句可以创建一个OUTLINECreateoereplaceoutlineOutLn_NameonSelectCol1,Col2fromTablewhere……如果要删除Outline,可以采用DropOutlineOutLn_Name;
对于已经创建了的OutLine,存放在OUTLN用户的OL$HINTS表下面对于有些语句,你可以使用updateoutln.ol$hints来更新outline如updateoutln.ol$hints(ol_name,'
TEST1'
'
TEST2'
TEST1)whereol_namein('
);
这样,你就把Test1OUTLINE与Test2OUTLINE互换了如果想利用已经存在的OUTLINE,需要设置以下参数Altersystem/sessionsetQuery_rewrite_enabled=trueAltersystem/sessionsetuse_stored_outlines=true[Q]v$sysstat中的class分别代表什么[A]统计类别1代表事例活动2代表Redobuffer活动4代表锁8代表数据缓冲活动16代表OS活动32代表并行活动64代表表访问128代表调试信息[Q]怎么杀掉特定的数据库会话[A]Altersystemkillsession'
sid,serial#'
或者altersystemdisconnectsession'
immediate;
在win上,还可以采用oracle提供的orakill杀掉一个线程(其实就是一个Oracle进程)在Linux/Unix上,可以直接利用kill杀掉数据库进程对应的OS进程[Q]怎么快速查找锁与锁等待[A]数据库的锁是比较耗费资源的,特别是发生锁等待的时候,我们必须找到发生等待的锁,有可能的话,杀掉该进程。
这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现,任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。
可以通过altersystemkillsession‘sid,serial#’来杀掉会话SELECT/*+rule*/s.username,decode(l.type,'
TM'
TABLELOCK'
'
TX'
ROWLOCK'
NULL)LOCK_LEVEL,o.owner,o.object_name,o.object_type,s.sid,s.serial#,s.terminal,s.machine,s.program,s.osuserFROMv$sessions,v$lockl,dba_objectsoWHEREl.sid=s.sidANDl.id1=o.object_id(+)ANDs.usernameisNOTNULL如果发生了锁等待,我们可能更想知道是谁锁了表而引起谁的等待以下的语句可以查询到谁锁了表,而谁在等待。
SELECT/*+rule*/lpad('
'
decode(l.xidusn,0,3,0))||l.oracle_usernameUser_name,o.owner,o.object_name,o.object_type,s.sid,s.serial#FROMv$locked_objectl,dba_objectso,v$sessionsWHEREl.object_id=o.object_idANDl.session_id=s.sidORDERBYo.object_id,xidusnDESC以上查询结果是一个树状结构,如果有子节点,则表示有等待发生。
如果想知道锁用了哪个回滚段,还可以关联到V$rollname,其中xidusn就是回滚段的USN[Q]如何有效的删除一个大表(extent数很多的表)[A]一个有很多(100k)extent的表,如果只是简单地用droptable的话,会很大量消耗CPU(Oracle要对fet$、uet$数据字典进行操作),可能会用上几天的时间,较好的方法是分多次删除extent,以减轻这种消耗:
1.truncatetablebig-tablereusestorage;
2.altertablebig-tabledeallocateunusedkeep2000m(原来大小的n-1/n);
3.altertablebig-tabledeallocateunusedkeep1500m;
....4.droptablebig-table;
[Q]如何收缩临时数据文件的大小[A]9i以下版本采用ALTERDATABASEDATAFILE'
filename'
RESIZE100M类似的语句9i以上版本采用ALTERDATABASETEMPFILE'
RESIZE100M注意,临时数据文件在使用时,一般不能收缩,除非关闭数据库或断开所有会话,停止对临时数据文件的使用。
[Q]怎么清理临时段[A]可以使用如下办法1、使用如下语句查看一下认谁在用临时段SELECTusername,sid,serial#,sql_address,machine,program,tablespace,segtype,contentsFROMv$sessionse,v$sort_usagesuWHEREse.saddr=su.session_addr2、那些正在使用临时段的进程SQL>
Altersystemkillsession'
3、把TEMP表空间回缩一下SQL>
AltertablespaceTEMPcoalesce;
还可以使用诊断事件1、确定TEMP表空间的ts#SQL>
selectts#,nameFROMv$tablespace;
TS#NAME-----------------------0SYSYEM1RBS2USERS3*TEMP……2、执行清理操作altersessionsetevents'
immediatetracenameDROP_SEGMENTSlevelTS#+1'
说明:
temp表空间的TS#为3*,SoTS#+1=4如果想清除所有表空间的临时段,则TS#=2147483647[Q]怎么样dump数据库内部结构,如上面显示的控制文件的结构[A]常见的有1、分析数据文件块,转储数据文件n的块maltersystemdumpdatafilenblockm2、分析日志文件altersystemdumplogfilelogfilename;
3、分析控制文件的内容altersessionsetevents'
immediatetracenameCONTROLFlevel10'
4、分析所有数据文件头altersessionsetevents'
immediatetracenameFILE_HDRSlevel10'
5、分析日志文件头altersessionsetevents'
immediatetracenameREDOHDRlevel10'
6、分析系统状态,最好每10分钟一次,做三次对比altersessionsetevents'
immediatetracenameSYSTEMSTATElevel10'
7、分析进程状态altersessionsetevents'
immediatetracenamePROCESSSTATElevel10'
8、分析LibraryCache的详细情况altersessionsetevents'
immediatetracenamelibrary_cachelevel10'
[Q]如何获得所有的事件代码[A]事件代码范围一般从10000to10999,以下列出了这个范围的事件代码与信息SETSERVEROUTPUTONDECLAREerr_msgVARCHAR2(120);
BEGINdbms_output.enable(1000000);
FORerr_numIN10000..10999LOOPerr_msg:
=SQLERRM(-err_num);
IFerr_msgNOTLIKE'
%Message'
||err_num||'
notfound%'
THENdbms_output.put_line(err_msg);
ENDIF;
ENDLOOP;
END;
/在Unix系统上,事件信息放在一个文本文件里$ORACLE_HOME/rdbms/mesg/oraus.msg可以用如下脚本查看事件信息event=10000while[$event-ne10999]doevent=`expr$event+1`oerrora$eventdone对于已经确保的/正在跟踪的事件,可以用如下脚本获得SETSERVEROUTPUTONDECLAREl_levelNUMBER;
BEGINFORl_eventIN10000..10999LOOPdbms_system.read_ev(l_event,l_level);
IFl_level>
0THENdbms_output.put_line('
Event'
||TO_CHAR(l_event)||'
issetatlevel'
||TO_CHAR(l_level));
/[Q]什么是STATSPACK,我怎么使用它?
[A]Statspack是Oracle8i以上提供的一个非常好的性能监控与诊断工具,基本上全部包含了BSTAT/ESTAT的功能,更多的信息可以参考附带文档$ORACLE_HOME/rdbms/admin/spdoc.txt。
安装Statspack:
cd$ORACLE_HOME/rdbms/adminsqlplus"
/assysdba"
@spdrop.sql--卸载,