ITPub博客

首页 > 数据库 > Oracle > 强烈推荐:ORACLE学习笔记--性能优化(ZT)

强烈推荐:ORACLE学习笔记--性能优化(ZT)

原创 Oracle 作者:jolly10 时间:2008-03-06 12:14:12 0 删除 编辑

在IXDBA看到的很不错的记录,特转载过来,以后要常来看看!

包括:

1. 查询正在执行语句的执行计划(也就是实际语句执行计划)

2.如何设置自动跟踪

3.如何跟踪自己的会话或者是别人的会话

4.怎么设置整个数据库系统跟踪

5.怎么样根据OS进程快速获得DB进程信息与正在执行的语句
6.怎么样快速重整索引

7.如何使用Hint提示

8.怎么样快速复制表或者是插入数据

10.Oracle什么时候会使用跳跃式索引扫描

11.怎么样创建使用虚拟索引 12.怎样监控无用的索引

13.怎么样能固定我的执行计划

14.v$sysstat中的class分别代表什么

15.怎么杀掉特定的数据库会话

16.怎么快速查找锁与锁等待

17.如何收缩临时数据文件的大小

18.怎么清理临时段

19.怎么样dump数据库内部结构,如上面显示的控制文件的结构
20.如何获得所有的事件代码

[@more@]

1. 查询正在执行语句的执行计划(也就是实际语句执行计划)

select * from v$sql_plan where hash_value = (select sql_hash_value from v$session where sid = 1111);

其中id和parent_id表示了执行数的结构,数值最大的为最先执行比如

ID PARENT_ID

-------------

0

1 0

2 1

3 2

4 3

5 4

6 3

则执行计划树为

0

1

2

3

6 4

5

2.如何设置自动跟踪

用system登录

执行$ORACLE_HOME/rdbms/admin/utlxplan.sql创建计划表

执行$ORACLE_HOME/sqlplus/admin/plustrce.sql创建plustrace角色

如果想计划表让每个用户都能使用,则

SQL>create public synonym plan_table for plan_table;

SQL> grant all on plan_table to public;

如果想让自动跟踪的角色让每个用户都能使用,则

SQL> grant plustrace to public;

通过如下语句开启/停止跟踪

SET AUTOTRACE

ON |OFF | ON EXPLAIN | ON STATISTICS | TRACEONLY | TRACEONLY EXPLAIN

3.如何跟踪自己的会话或者是别人的会话

跟踪自己的会话很简单

Alter session set sql_trace true|false

Or

Exec dbms_session.set_sql_trace(TRUE);

如果跟踪别人的会话,需要调用一个包

exec dbms_system.set_sql_trace_in_session(sid,serial#,true|false)

跟踪的信息在user_dump_dest 目录下可以找到或通过如下脚本获得文件名称(适用于Win环境,如果是unix需要做一定修改)

SELECT p1.value||''||p2.value||'_ora_'||p.spid||'.ora' filename

FROM

v$process p,

v$session s,

v$parameter p1,

v$parameter p2

WHERE p1.name = 'user_dump_dest'

AND p2.name = 'db_name'

AND p.addr = s.paddr

AND s.audsid = USERENV ('SESSIONID')

最后,可以通过tkprof来解析跟踪文件,如

tkprof 原文件 目标文件 sys=n

4.怎么设置整个数据库系统跟踪

其实文档上的alter system set sql_trace=true是不成功的,但是可以通过设置事件来完成这个工作,作用相等

alter system set events

'10046 trace name context forever,level 1';

如果关闭跟踪,可以用如下语句

alter system set events

'10046 trace name context off';

其中的level 1与上面的8都是跟踪级别

level 1:跟踪SQL语句,等于sql_trace=true

level 4:包括变量的详细信息

level 8:包括等待事件

level 12:包括绑定变量与等待事件

5.怎么样根据OS进程快速获得DB进程信息与正在执行的语句有些时候,我们在OS上操作,象TOP之后我们得到的OS进程,怎么快速根据OS信息获得DB信息呢?我们可以编写如下脚本:$more whoit.sh
#!/bin/sh
sqlplus /nolog 100,cascade=> TRUE);
dbms_stats.gather_table_stats(User,TableName,degree => 4,cascade => true);

这是对命令与工具包的一些总结
<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
有重建整个索引数的功能,可以在不删除原始索引的情况下改变索引的存储参数语法为alter index index_name rebuild tablespace ts_name
storage(......);

如果要快速重建整个用户下的索引,可以用如下脚本,当然,需要根据你自己的情况做相应修改SQL> set heading off
SQL> set feedback off
SQL> spool d:index.sql
SQL> SELECT 'alter index ' || index_name || ' rebuild '
||'tablespace INDEXES storage(initial 256K next 256K pctincrease 0);'
FROM all_indexes
WHERE ( tablespace_name != 'INDEXES'
OR next_extent != ( 256 * 1024 )
)
AND owner = USER
SQL>spool off

另外一个合并索引的语句是
alter index index_name coalesce

这个语句仅仅是合并索引中同一级的leaf block,消耗不大,对于有些索引中存在大量空间浪费的情况下,有一些作用。

7.如何使用Hint提示在select/delete/update后写/*+ hint */如 select /*+ index(TABLE_NAME INDEX_NAME) */ col1...

注意/*和+之间不能有空格,如用hint指定使用某个索引select /*+ index(cbotab) */ col1 from cbotab;
select /*+ index(cbotab cbotab1) */ col1 from cbotab;
select /*+ index(a cbotab1) */ col1 from cbotab a;

其中
TABLE_NAME
是必须要写的,且如果在查询中使用了表的别名,在hint也要用表的别名来代替表名;
INDEX_NAME
可以不必写,Oracle会根据统计值选一个索引;如果索引名或表名写错了,那这个hint就会被忽略;

8.怎么样快速复制表或者是插入数据快速复制表可以指定Nologging选项如:Create table t1 nologging
as select * from t2;

快速插入数据可以指定append提示,但是需要注意noarchivelog模式下,默认用了append就是nologging模式的。 在archivelog下,需要把表设置程Nologging模式。如insert /*+ append */ into t1
select * from t2

注意:如果在9i环境中并设置了FORCE LOGGING,则以上操作是无效的,并不会加快,当然,可以通过如下语句设置为NO FORCE LOGGING。Alter database no force logging;是否开启了FORCE LOGGING,可以用如下语句查看SQL> select force_logging from v$database;

在很多时候,Oracle会错误的使用索引而导致效率的明显下降,我们可以使用一点点技巧而避免使用不该使用的索引,如:表test,有字段a,b,c,d,在a,b,c上建立联合索引inx_a(a,b,c),在b上单独建立了一个索引Inx_b(b)。

在正常情况下,where a=? and b=? and c=?会用到索引inx_a,where b=?会用到索引inx_b,但是,where a=? and b=? and c=? group by b会用到哪个索引呢?在分析数据不正确(很长时间没有分析)或根本没有分析数据的情况下,oracle往往会使用索引inx_b。通过执行计划的分析,这个索引的使用,将大大耗费查询时间。

当然,我们可以通过如下的技巧避免使用inx_b,而使用inx_a。

where a=? and b=? and c=? group by b||'' --如果b是字符
where a=? and b=? and c=? group by b+0 --
如果b是数字

通过这样简单的改变,往往可以是查询时间提交很多倍当然,我们也可以使用no_index提示,相信很多人没有用过,也是一个不错的方法:

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/271283/viewspace-1000485/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-02-20

  • 博文量
    263
  • 访问量
    826723