最近也工作一段时间了,发现俺还是忠实的热爱数据库啊。
传给我最近开始总结的数据库经验,欢迎大家多多捧场。
每周周末更新。如你们有问题可以在我的bolg上留言。
1. 数据字典
1.1查询数据字典。
d
ictionary
-----
该字典包含所有的字典信息
SQL>select * from dict where instr(comments,'index')>0;
-----
查询所有有关
index
的数据字典名称。
1.2设置查询结果格式。
Set heading on/off
:
打开
/
关闭查询结果表头的显示
,
默认为
ON
。
Set feedback on/off
:
打开
/
关闭查询结果中返回行数的显示
,
默认为
ON
。
Set echo on/off
:
打开
/
关闭命令的回显
,
默认为
ON
。
Set time on/off
:
打开
/
关闭时间显示
,
默认为
OFF
。
2.系统I/O调整
2.1查询磁盘I/O情况。
#select d.tablespace_name tablespace,d.file_name,f.phyrds,f.phywrts
from v$filestat f,dba_data_files d
where f.file#=d.file_id; ---------
查询数据文件的读写情况
#db_file_multiblock_read_count ---------
一次性读入块的数量,可以在
session
级别设置。
3. SQL调整
3.1 关于sql的初始化参数调整。
#cursor_sharing
-------
是否会自动匹配变量参数
| exact
(完全不会)
------
该参数如果不配合绑定变量会使得系统开销很大
| similar
(智能匹配)
-------
推荐使用,但性能不如
exact
加绑定变量好
|force
(强制)
-------
会产生
BUG|
#
查看
sqlarea
中的
sql
语句来断定其
sql
所执行的次数(字段
EXECUTIONS
)。其动态性能视图为
v$sqlarea
3.2 打开游标和使用绑定变量的方法。
游标:
variable x refcursor ----
定义
x
为一个游标
Begin
Open :x for select XXXXXXX from XXXXXXXX;
End;
/
(
如果你想读取游标中的数,可以使用
print x)
绑定变量:
sqlplus
中可以这样绑定
SQL> var n varchar2(30);
SQL> exec :n := 'IM_USER';
PL/SQL
过程已成功完成。
SQL> select * from tab where tname = :n;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
IM_USER SYNONYM
3.3 sql_trace使用。
#
打开跟踪文件
Alter session set sql_trace=true;
grant alter session to xxx
;
---
给予
alter session
自己的跟踪文件的位置(要使用下面的语句必须具有可查找动态性能视图的权限)
select c.value||'/'||d.instance_name||'_ora_'||a.spid||'.trc' trace
from v$process a,v$session b,v$parameter c,v$instance d
where a.addr=b.paddr and b.audsid=userenv('sessionid') and c.name ='user_dump_dest';
跟踪别人的跟踪文件的位置
select c.value||'/'||d.instance_name||'_ora_'||a.spid||'.trc' trace
from v$process a,v$session b,v$parameter c,v$instance d
where a.addr=b.paddr and b.audsid=&a and c.name ='user_dump_dest';
b.audsid
的值指定了所跟踪的
session
可以由
select SID,SERIAL#,AUDSID,username from v$session;
得出
#
加标记
Alter session set tracefile_identifier=’
你想加的标记名
’;
再打开跟踪文件
#
跟踪别人的
sql
如果跟踪别人的会话,需要调用一个包
exec dbms_system.set_sql_trace_in_session(sid,serial#,true|false)
跟踪的信息在
user_dump_dest
目录下可以找到
可以通过
Tkprof
来解析跟踪文件,如
Tkprof
原文件
目标文件
sys=n
3.4 10046tarce
10046
是
sql_trace
的一个提升,它能够提供更为详细的信息
alter session set events '10046 trace name context forever, level xx';
(必须确保
timed_statistics
为
true
)
10046event
的追踪级别大致有:
level 1
:跟踪
sql
语句,包括解析、执行、提取、提交和回滚等。
level 4
:包括变量的周详信息
level 8
:包括等待事件
level 12
:包括绑定变量和等待事件
关闭命令为
alter session set events '10046 trace name context off';
#
查看当前10046等级
(11g貌似有问题,待研究)
Grant
execute on dbms_system to xxxxx;
set serveroutput on
declare i_event number;
begin
sys.dbms_system.read_ev(10046,i_event);
dbms_output.put_line('the session sql_trace level is:'||i_event);
end;
/
#
如果要监控别人的在拥有
dbms_system.set_ev
权限的用户上运行
exec dbms_system.set_ev(SID,
SERIAL#,10046,
等级,'');(SID, SERIAL#在v$session上获得)
等级为(1,4,8,12,0)---0为关闭。
所跟踪产生的文件为被跟踪session的tracefile.
3.5关于sql的执行计划。
SET AUTOTRACE OFF ----------------
不生成
AUTOTRACE
报告,这是缺省模式
SET AUTOTRACE ON EXPLAIN ------ AUTOTRACE
只显示优化器执行路径报告
SET AUTOTRACE ON STATISTICS --
只显示执行统计信息
SET AUTOTRACE ON -----------------
包含执行计划和统计信息
SET AUTOTRACE TRACEONLY ------
同
set autotrace on
,但是不显示查询输出
SET AUTOTRACE TRACEONLY EXPLAIN -----
只显示执行计划,并不执行语句。
AUTOTRACE Statistics
常用列解释
db block gets -----
从
buffer cache
中读取的
block
的数量
consistent gets
从
buffer cache -----
中读取的
undo
数据的
block
的数量
physical reads -----
从磁盘读取的
block
的数量
redo size ----- DML
生成的
redo
的大小
sorts (memory) -----
在内存执行的排序量
sorts (disk) -----
在磁盘上执行的排序量
3.6 tkprof解读
parse(
分析
)
:在共享池中找到该查询(软分析)或者创建该查询的新计划(硬分析)
execute(
执行
)
:执行查询的所有工作
fetch(
提取
)
:显示
select
的提取工作,对于
update
,则没有内容
count(
计数
):
执行的次数
cpu:
此阶段
cpu
的耗时,以毫秒为单位
elapsed(
占用时间
):
挂钟时间,如果大于
cpu
时间,则有等待时间
disk(
磁盘
)
:执行物理
I/O
的次数
QUERY(
查询
):
检索一致性执行的
I/O
次数
CURRENT(
当前
)
:到当前多执行的逻辑
I/O
次数
ROW:
此阶段被处理或者受到影响的行
如果一个
UPDATE
语句
EXECUTE
的
QUERY,CURRENT
,
ROWS
分别为
2000 1000 500,
表示这个语句访问了
2000
个块找到需要
UPDATE
的行记录,在
UPDATE
的时候只访问了
1000
个块,一共更新了
500
行。如果只获取很少的数据,而要访问了大量的块,表明
SQL
与需要优化了。
MISSES
缓存命中率:
0
表示已经通过软分析
OPTIMIZER GOAL
(优化程序目标)
3.7巧用rownum。
记住
rownum
是伪例,他永远从
1
开始,也就是说
select xxxx from xxxxx where rownum>5
这样的是不可能产生结果的。那如果你一定要这么做怎么办呢可以使用
select * from (select rownum as rn,t.* from xxxx t) where rn>10
;
详细请见附件