ORACLE学习笔记之调节性能优化篇 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1. 查询正在执行语句的执行计划(也就是实际语句执行计划)
其中id和parent_id表示了执行数的结构,数值最大的为最先执行 比如
则执行计划树为
2.如何设置自动跟踪 用system登录 执行$ORACLE_HOME/rdbms/admin/utlxplan.sql创建计划表 执行$ORACLE_HOME/sqlplus/admin/plustrce.sql创建plustrace角色 如果想计划表让每个用户都能使用,则
如果想让自动跟踪的角色让每个用户都能使用,则
通过如下语句开启/停止跟踪
3.如何跟踪自己的会话或者是别人的会话 跟踪自己的会话很简单
如果跟踪别人的会话,需要调用一个包
跟踪的信息在user_dump_dest 目录下可以找到或通过如下脚本获得文件名称(适用于Win环境,如果是unix需要做一定修改)
最后,可以通过Tkprof来解析跟踪文件,如
4.怎么设置整个数据库系统跟踪 其实文档上的alter system set sql_trace=true是不成功的,但是可以通过设置事件来完成这个工作,作用相等
如果关闭跟踪,可以用如下语句
其中的level 1与上面的8都是跟踪级别 level 1:跟踪SQL语句,等于sql_trace=true level 4:包括变量的详细信息 level 8:包括等待事件 level 12:包括绑定变量与等待事件 5.怎么样根据OS进程快速获得DB进程信息与正在执行的语句 有些时候,我们在OS上操作,象TOP之后我们得到的OS进程,怎么快速根据OS信息获得DB信息呢? 我们可以编写如下脚本:
这是对命令与工具包的一些总结 <1>、对于分区表,建议使用DBMS_STATS,而不是使用Analyze语句。 a) 可以并行进行,对多个用户,多个Table b) 可以得到整个分区表的数据和单个分区的数据。 c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区 d) 可以倒出统计信息 e) 可以用户自动收集统计信息 <2>、DBMS_STATS的缺点 a) 不能Validate Structure b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。 c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True <3>、对于oracle 9里面的External Table,Analyze不能使用,只能使用DBMS_STATS来收集信息。 6.怎么样快速重整索引 通过rebuild语句,可以快速重整或移动索引到别的表空间 rebuild有重建整个索引数的功能,可以在不删除原始索引的情况下改变索引的存储参数 语法为
如果要快速重建整个用户下的索引,可以用如下脚本,当然,需要根据你自己的情况做相应修改
另外一个合并索引的语句是
这个语句仅仅是合并索引中同一级的leaf block,消耗不大,对于有些索引中存在大量空间浪费的情况下,有一些作用。 7.如何使用Hint提示 在select/delete/update后写/*+ hint */ 如
注意/*和+之间不能有空格,如用hint指定使用某个索引
其中 TABLE_NAME是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名; INDEX_NAME可以不必写,Oracle会根据统计值选一个索引; 如果索引名或表名写错了,那这个hint就会被忽略;
8.怎么样快速复制表或者是插入数据 快速复制表可以指定Nologging选项 如:
快速插入数据可以指定append提示,但是需要注意noarchivelog模式下,默认用了append就是nologging模式的。 在archivelog下,需要把表设置程Nologging模式。 如
注意:如果在9i环境中并设置了FORCE LOGGING,则以上操作是无效的,并不会加快,当然,可以通过如下语句设置为NO FORCE LOGGING。
是否开启了FORCE LOGGING,可以用如下语句查看
举例: 本来在CM_USER上有索引IDX_CM_USER4(ACC_ID)和IDX_CM_USER8(BILL_ID),可是执行如下语句的时候很慢。
用explain分析,发现执行计划是用IDX_CM_USER8.如下查询
发现IDX_CM_USER8没有分析过。 用下面语句执行计划改变
或者分析索引
可以发现执行计划恢复正常。 10.Oracle什么时候会使用跳跃式索引扫描 这是9i的一个新特性跳跃式索引扫描(Index Skip Scan). 例如表有索引index(a,b,c),当查询条件为where b=?的时候,可能会使用到索引index(a,b,c),如,执行计划中出现如下计划: INDEX (SKIP SCAN) OF 'TEST_IDX' (NON-UNIQUE) Oracle的优化器(这里指的是CBO)能对查询应用Index Skip Scans至少要有几个条件: <1> 优化器认为是合适的。 <2> 索引中的前导列的唯一值的数量能满足一定的条件(如重复值很多)。 <3> 优化器要知道前导列的值分布(通过分析/统计表得到)。 <4> 合适的SQL语句 等。 11.怎么样创建使用虚拟索引 可以使用nosegment选项,如
如果在哪个session需要测试虚拟索引,可以利用隐含参数来处理 alter session set "_use_nosegment_indexes" = true; 就可以利用explain plan for select ……来看虚拟索引的效果,利用
查看执行计划,最后,根据需要,我们可以删除虚拟索引,如普通索引一样
注意:虚拟索引并不是物理存在的,所以虚拟索引并不等同于物理索引,不要用自动跟踪去测试虚拟索引,因为那是实际执行的效果,是用不到虚拟索引的。 12.怎样监控无用的索引 Oracle 9i以上,可以监控索引的使用情况,如果一段时间内没有使用的索引,一般就是无用的索引 语法为:
当然,如果想监控整个用户下的索引,可以采用如下的脚本:
13.怎么样能固定我的执行计划 可以使用OUTLINE来固定SQL语句的执行计划,用如下语句可以创建一个OUTLINE
如果要删除Outline,可以采用
对于已经创建了的OutLine,存放在OUTLN用户的OL$HINTS表下面,对于有些语句,你可以使用update outln.ol$hints来更新outline,如
这样,你就把Test1 OUTLINE与Test2 OUTLINE互换了,如果想利用已经存在的OUTLINE,需要设置以下参数
14.v$sysstat中的class分别代表什么 统计类别 1 代表事例活动 2 代表Redo buffer活动 4 代表锁 8 代表数据缓冲活动 16 代表OS活动 32 代表并行活动 64 代表表访问 128 代表调试信息 15.怎么杀掉特定的数据库会话
或者
在win上,还可以采用oracle提供的orakill杀掉一个线程(其实就是一个Oracle进程) 在Linux/Unix上,可以直接利用kill杀掉数据库进程对应的OS进程
16.怎么快速查找锁与锁等待 数据库的锁是比较耗费资源的,特别是发生锁等待的时候,我们必须找到发生等待的锁,有可能的话,杀掉该进程。 这个语句将查找到数据库中所有的DML语句产生的锁,还可以发现,任何DML语句其实产生了两个锁,一个是表锁,一个是行锁。 可以通过alter system kill session ‘sid,serial#’来杀掉会话
如果发生了锁等待,我们可能更想知道是谁锁了表而引起谁的等待,以下的语句可以查询到谁锁了表,而谁在等待。
以上查询结果是一个树状结构,如果有子节点,则表示有等待发生。如果想知道锁用了哪个回滚段,还可以关联到V$rollname,其中xidusn就是回滚段的USN [Q] 如何有效的删除一个大表(extent数很多的表) [A] 一个有很多(100k)extent的表,如果只是简单地用drop table的话,会很大量消耗CPU(Oracle要对fet$、uet$数据字典进行操作),可能会用上几天的时间,较好的方法是分多次删除extent,以减轻这种消耗:
17.如何收缩临时数据文件的大小 9i以下版本采用
类似的语句 9i以上版本采用
注意,临时数据文件在使用时,一般不能收缩,除非关闭数据库或断开所有会话,停止对临时数据文件的使用。 18.怎么清理临时段 可以使用如下办法 <1>、 使用如下语句查看一下认谁在用临时段
<2>、 那些正在使用临时段的进程
<3>、把TEMP表空间回缩一下
还可以使用诊断事件 <1>、 确定TEMP表空间的ts#
<2>、 执行清理操作
说明: temp表空间的TS# 为 3*, So TS#+ 1= 4,如果想清除所有表空间的临时段,则,TS# = 2147483647
19.怎么样dump数据库内部结构,如上面显示的控制文件的结构 常见的有 1、分析数据文件块,转储数据文件n的块m
2、分析日志文件
3、分析控制文件的内容
4、分析所有数据文件头
5、分析日志文件头
6、分析系统状态,最好每10分钟一次,做三次对比
7、分析进程状态
8、分析Library Cache的详细情况
20.如何获得所有的事件代码 事件代码范围一般从10000 to 10999,以下列出了这个范围的事件代码与信息
在Unix系统上,事件信息放在一个文本文件里 $ORACLE_HOME/rdbms/mesg/oraus.msg 可以用如下脚本查看事件信息
对于已经确保的/正在跟踪的事件,可以用如下脚本获得
21.什么是STATSPACK,我怎么使用它? Statspack是Oracle 8i以上提供的一个非常好的性能监控与诊断工具,基本上全部包含了BSTAT/ESTAT的功能,更多的信息,可以参考附带文档$ORACLE_HOME/rdbms/admin/spdoc.txt。 安装Statspack: cd $ORACLE_HOME/rdbms/admin sqlplus "/ as sysdba" @spdrop.sql -- 卸载,第一次可以不需要 sqlplus "/ as sysdba" @spcreate.sql -- 需要根据提示输入表空间名 使用Statspack: sqlplus perfstat/perfstat exec statspack.snap; -- 进行信息收集统计,每次运行都将产生一个快照号 -- 获得快照号,必须要有两个以上的快照,才能生成报表 select SNAP_ID, SNAP_TIME from STATS$SNAPSHOT; @spreport.sql -- 输入需要查看的开始快照号与结束快照号 其他相关脚本s: spauto.sql - 利用dbms_job提交一个作业,自动的进行STATPACK的信息收集统计 sppurge.sql - 清除一段范围内的统计信息,需要提供开始快照与结束快照号 sptrunc.sql - 清除(truncate)所有统计信息
22. SQL语句的优化方法 <1> /*+ALL_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化. 例如:
<2>. /*+FIRST_ROWS*/ 表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化. 例如:
<3>. /*+CHOOSE*/ 表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量; 表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法; 例如:
<4>. /*+RULE*/ 表明对语句块选择基于规则的优化方法. 例如:
<5>. /*+FULL(TABLE)*/ 表明对表选择全局扫描的方法. 例如:
<6>. /*+ROWID(TABLE)*/ 提示明确表明对指定表根据ROWID进行访问. 例如:
<7>. /*+CLUSTER(TABLE)*/ 提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效. 例如:
<8>. /*+INDEX(TABLE INDEX_NAME)*/ 表明对表选择索引的扫描方法. 例如:
<9>. /*+INDEX_ASC(TABLE INDEX_NAME)*/ 表明对表选择索引升序的扫描方法. 例如:
<10>. /*+INDEX_COMBINE*/ 为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的 布尔组合方式. 例如:
<11>. /*+INDEX_JOIN(TABLE INDEX_NAME)*/ 提示明确命令优化器使用索引作为访问路径. 例如:
<12>. /*+INDEX_DESC(TABLE INDEX_NAME)*/ 表明对表选择索引降序的扫描方法. 例如:
<13>. /*+INDEX_FFS(TABLE INDEX_NAME)*/ 对指定的表执行快速全索引扫描,而不是全表扫描的办法. 例如:
<14>. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/ 提示明确进行执行规划的选择,将几个单列索引的扫描合起来. 例如:
<15>. /*+USE_CONCAT*/ 对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询. 例如:
<16>. /*+NO_EXPAND*/ 对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展. 例如:
<17>. /*+NOWRITE*/ 禁止对查询块的查询重写操作. <18>. /*+REWRITE*/ 可以将视图作为参数. <19>. /*+MERGE(TABLE)*/ 能够对视图的各个查询进行相应的合并. 例如:
<20>. /*+NO_MERGE(TABLE)*/对于有可合并的视图不再合并. 例如:
<21>. /*+ORDERED*/ 根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接. 例如:
<22>. /*+USE_NL(TABLE)*/ 将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表. 例如:
<23>. /*+USE_MERGE(TABLE)*/ 将指定的表与其他行源通过合并排序连接方式连接起来. 例如:
<24>. /*+USE_HASH(TABLE)*/ 将指定的表与其他行源通过哈希连接方式连接起来. 例如:
<25>. /*+DRIVING_SITE(TABLE)*/ 强制与ORACLE所选择的位置不同的表进行查询执行. 例如:
<26>. /*+LEADING(TABLE)*/ 将指定的表作为连接次序中的首表. <27>. /*+CACHE(TABLE)*/ 当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端 例如:
<28>. /*+NOCACHE(TABLE)*/ 当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端 例如:
<29>. /*+APPEND*/ 直接插入到表的最后,可以提高速度.
<30>. /*+NOAPPEND*/ 通过在插入语句生存期内停止并行模式来启动常规插入.
<31>.parallel direct-load insert
|