Skip to content

Data access tuning - 3. page

在Oracle监控中如何捕获执行计划变更的语句

在通常的数据库运维中,经常担心数据库一些重要的SQL的性能突然变差,导致整个数据库性能糟糕响应缓慢,甚至让数据库瘫痪的情况时有出现,往往这个时候要在事后通过awrsqrpt.sql脚本从top sql中去抓取分析执行变化的SQL语句,今天脑袋一闪想有没有办法有脚本可以自己去对比呢?回家就开始敲命令测试,测试的平台为11gr1版本,通过dba_hist_sqlstats数据字典中抓去sql id数据进行对比,通过对比获取相关的SQL_ID,以及此SQL的最优执行计划是什么。通过该sql可以设定一个固定的执行时间,通过分别查出来的数据进行监控,对执行计划产生误差的语句及时的通过SQL_PROFILE或者SPM(11g)调整成最优执行计划。

具体语句如下:

spool sql_have_logs_plan.txt
set lines 220 pages 9999 trimspool on
set numformat 999,999,999
column plan_hash_value format 99999999999999
column min_snap format 999999
column max_snap format 999999
column min_avg_ela format 999,999,999,999,999
column avg_ela format 999,999,999,999,999
column ela_gain format 999,999,999,999,999
select sql_id,
       min(min_snap_id) min_snap,
       max(max_snap_id) max_snap,
       max(decode(rw_num,1,plan_hash_value)) plan_hash_value,
       max(decode(rw_num,1,avg_ela)) min_avg_ela,
       avg(avg_ela) avg_ela,
       avg(avg_ela) - max(decode(rw_num,1,avg_ela)) ela_gain,
       -- max(decode(rw_num,1,avg_buffer_gets)) min_avg_buf_gets,
       -- avg(avg_buffer_gets) avg_buf_gets,
       max(decode(rw_num,1,sum_exec))-1 min_exec,
       avg(sum_exec)-1 avg_exec
from (
  select sql_id, plan_hash_value, avg_buffer_gets, avg_ela, sum_exec,
         row_number() over (partition by sql_id order by avg_ela) rw_num , min_snap_id, max_snap_id
  from
  (
    select sql_id, plan_hash_value , sum(BUFFER_GETS_DELTA)/(sum(executions_delta)+1) avg_buffer_gets,
    sum(elapsed_time_delta)/(sum(executions_delta)+1) avg_ela, sum(executions_delta)+1 sum_exec,
    min(snap_id) min_snap_id, max(snap_id) max_snap_id
    from dba_hist_sqlstat a
    where exists  (
       select sql_id from dba_hist_sqlstat b where a.sql_id = b.sql_id
         and  a.plan_hash_value != b.plan_hash_value
         and  b.plan_hash_value > 0)
    and plan_hash_value > 0
    group by sql_id, plan_hash_value
    order by sql_id, avg_ela
  )
  order by sql_id, avg_ela
  )
group by sql_id
having max(decode(rw_num,1,sum_exec)) > 1
order by 7 desc
/
spool off
clear columns
set numformat 9999999999

具体的执行结果参考如下:

SQL> spool sql_with_more_than_1plan.txt
set lines 220 pages 9999 trimspool on
SQL> SQL> set numformat 999,999,999
SQL> column plan_hash_value format 99999999999999
SQL> column min_snap format 999999
SQL> column max_snap format 999999
SQL> column min_avg_ela format 999,999,999,999,999
SQL> column avg_ela format 999,999,999,999,999
SQL> column ela_gain format 999,999,999,999,999
SQL> select sql_id,
2 min(min_snap_id) min_snap,
3 max(max_snap_id) max_snap,
4 max(decode(rw_num,1,plan_hash_value)) plan_hash_value,
5 max(decode(rw_num,1,avg_ela)) min_avg_ela,
6 avg(avg_ela) avg_ela,
7 avg(avg_ela) - max(decode(rw_num,1,avg_ela)) ela_gain,
8 -- max(decode(rw_num,1,avg_buffer_gets)) min_avg_buf_gets,
9 -- avg(avg_buffer_gets) avg_buf_gets,
10 max(decode(rw_num,1,sum_exec))-1 min_exec,
11 avg(sum_exec)-1 avg_exec
12 from (
13 select sql_id, plan_hash_value, avg_buffer_gets, avg_ela, sum_exec,
14 row_number() over (partition by sql_id order by avg_ela) rw_num , min_snap_id, max_snap_id
15 from
16 (
17 select sql_id, plan_hash_value , sum(BUFFER_GETS_DELTA)/(sum(executions_delta)+1) avg_buffer_gets,
18 sum(elapsed_time_delta)/(sum(executions_delta)+1) avg_ela, sum(executions_delta)+1 sum_exec,
19 min(snap_id) min_snap_id, max(snap_id) max_snap_id
20 from dba_hist_sqlstat a
21 where exists (
22 select sql_id from dba_hist_sqlstat b where a.sql_id = b.sql_id
23 and a.plan_hash_value != b.plan_hash_value
24 and b.plan_hash_value > 0)
25 and plan_hash_value > 0
26 group by sql_id, plan_hash_value
27 order by sql_id, avg_ela
28 )
29 order by sql_id, avg_ela
30 )
31 group by sql_id
32 having max(decode(rw_num,1,sum_exec)) > 1
33 order by 7 desc
34 /
spool off
clear columns
set numformat 9999999999
SQL_ID MIN_SNAP MAX_SNAP PLAN_HASH_VALUE MIN_AVG_ELA AVG_ELA ELA_GAIN MIN_EXEC AVG_EXEC
------------- -------- -------- --------------- -------------------- -------------------- -------------------- ------------ ------------
gfjvxb25b773h 192 204 3801470479 6,368 171,152 164,784 1 1
7asddw0r2wykx 192 211 3660107835 10,311 16,448 6,137 57 30
7ng34ruy5awxq 192 209 2606284882 117 320 204 426 1,371
g278wv0zzpn5j 195 211 3142739690 0 189 189 72 63
1gu8t96d0bdmu 192 209 2035254952 67 154 87 826 1,134
bsa0wjtftg3uw 193 211 2020579421 0 18 18 224 191
0kugqg48477gf 201 202 3321035584 0 0 0 19 27

7 rows selected.

通过以上查询我们发现了7个结果,其中MIN_SNAP和MAX_SNAP代表该sql_id所代表最早出现时候的快照和最后一次出现的快照;PLAN_HASH_VALUE代表着最佳的执行计划;ELA_GAIN字段代表如果使用最佳的执行计划,与平均执行时间能够提速多少时间。

在查出结果后,我们可以通过sql profile(参考老刘的《验证sql_profile的执行计划》),也可以通过11g的dbms_spm.load_plans_from_cursor_cache更改相关Sql_id的sql的执行计划,这里以11g为例子做如下变更,对上面查询到的7asddw0r2wykx语句执行计划改为最优:

SQL> variable v_sqlid number
SQL> begin
2 :v_sqlid :=
3 dbms_spm.load_plans_from_cursor_cache(
4 sql_id=>'&sql_id',
5 plan_hash_value=>&plan_hash,
6 fixed=>'YES');
7 end;
8 /
Enter value for sql_id: 7asddw0r2wykx
old 4: sql_id=>'&sql_id',
new 4: sql_id=>'7asddw0r2wykx',
Enter value for plan_hash: 3660107835
old 5: plan_hash_value=>&plan_hash,
new 5: plan_hash_value=>3660107835,

PL/SQL procedure successfully completed.

关于分区表最多可拥有多少分区

群里一个小姑娘问起这个问题,分区表最多可以允许有多少个分区,CONCEPTS里有说到相关的信息在“18 Partitioned Tables and Indexes”中:

10g:

Partitioned Tables
Tables can be partitioned into up to 1024K-1 separate partitions.
Any table can be partitioned except those tables containing columns with LONG or LONG RAW datatypes.
You can, however, use tables containing columns with CLOB or BLOB datatypes.

浅谈如何了解一个B-tree索引的变化过程

索引在我们日常维护数据库的性能中占用非常大的比例,如何维护好你的索引很大程度上关系着数据库的性能,当然了索引只是性能调整中数据model的一部分,本文只是大头根据对索引的理解结合脚本来浅浅的对b-tree索引的变化做一个描述,权当饭后谈资,有错误和需要弥补的地方还要靠大家指正.

b-tree索引是啥我就不解释了,不懂的朋友参考oracle concept或者摸下度娘.很多dba都知道,维护索引无外乎如下几种情况:

1.索引有没有
2.索引设计合不合理
3.索引碎片太多了
4.索引过大了,虚胖
5.索引聚簇因不同步

郁闷碰到故障了··rac disgroup 起不来~先去trouble shooting了.

后续补上.

show_space脚本:快速检测表的存储信息

Tom在很多年前写了一个脚本工具showspace用来分析空间使用情况,此工具使用起来很方便可以快速了解表的存储信息。具体如下:

create or replace procedure show_space
( p_segname_1 in varchar2,
p_owner_1 in varchar2 default user,
p_type_1 in varchar2 default 'TABLE',
p_space in varchar2 default 'AUTO',
p_analyzed in varchar2 default 'Y'
)
as
p_segname varchar2(100);
p_type varchar2(10);
p_owner varchar2(30);

l_unformatted_blocks number;
l_unformatted_bytes number;
l_fs1_blocks number;
l_fs1_bytes number;
l_fs2_blocks number;
l_fs2_bytes number;
l_fs3_blocks number;
l_fs3_bytes number;
l_fs4_blocks number;
l_fs4_bytes number;
l_full_blocks number;
l_full_bytes number;

l_free_blks number;
l_total_blocks number;
l_total_bytes number;
l_unused_blocks number;
l_unused_bytes number;
l_LastUsedExtFileId number;
l_LastUsedExtBlockId number;
l_LAST_USED_BLOCK number;

procedure p( p_label in varchar2, p_num in number )
is
begin
dbms_output.put_line( rpad(p_label,40,'.') ||
p_num );
end;
begin
p_segname := upper(p_segname_1); -- rainy changed
p_owner := upper(p_owner_1);
p_type := p_type_1;

if (p_type_1 = 'i' or p_type_1 = 'I') then --rainy changed
p_type := 'INDEX';
end if;

if (p_type_1 = 't' or p_type_1 = 'T') then --rainy changed
p_type := 'TABLE';
end if;

if (p_type_1 = 'c' or p_type_1 = 'C') then --rainy changed
p_type := 'CLUSTER';
end if;

dbms_space.unused_space
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
total_blocks => l_total_blocks,
total_bytes => l_total_bytes,
unused_blocks => l_unused_blocks,
unused_bytes => l_unused_bytes,
LAST_USED_EXTENT_FILE_ID => l_LastUsedExtFileId,
LAST_USED_EXTENT_BLOCK_ID => l_LastUsedExtBlockId,
LAST_USED_BLOCK => l_LAST_USED_BLOCK );

if p_space = 'MANUAL' or (p_space <> 'auto' and p_space <> 'AUTO') then
dbms_space.free_blocks
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
freelist_group_id => 0,
free_blks => l_free_blks );

p( 'Free Blocks', l_free_blks );
end if;

p( 'Total Blocks', l_total_blocks );
p( 'Total Bytes', l_total_bytes );
p( 'Unused Blocks', l_unused_blocks );
p( 'Unused Bytes', l_unused_bytes );
p( 'Last Used Ext FileId', l_LastUsedExtFileId );
p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
p( 'Last Used Block', l_LAST_USED_BLOCK );

/*IF the segment is analyzed */
if p_analyzed = 'Y' then
dbms_space.space_usage(segment_owner => p_owner ,
segment_name => p_segname ,
segment_type => p_type ,
unformatted_blocks => l_unformatted_blocks ,
unformatted_bytes => l_unformatted_bytes,
fs1_blocks => l_fs1_blocks,
fs1_bytes => l_fs1_bytes ,
fs2_blocks => l_fs2_blocks,
fs2_bytes => l_fs2_bytes,
fs3_blocks => l_fs3_blocks ,
fs3_bytes => l_fs3_bytes,
fs4_blocks => l_fs4_blocks,
fs4_bytes => l_fs4_bytes,
full_blocks => l_full_blocks,
full_bytes => l_full_bytes);
dbms_output.put_line(rpad(' ',50,'*'));
dbms_output.put_line('The segment is analyzed');
p( '0% -- 25% free space blocks', l_fs1_blocks);
p( '0% -- 25% free space bytes', l_fs1_bytes);
p( '25% -- 50% free space blocks', l_fs2_blocks);
p( '25% -- 50% free space bytes', l_fs2_bytes);
p( '50% -- 75% free space blocks', l_fs3_blocks);
p( '50% -- 75% free space bytes', l_fs3_bytes);
p( '75% -- 100% free space blocks', l_fs4_blocks);
p( '75% -- 100% free space bytes', l_fs4_bytes);
p( 'Unused Blocks', l_unformatted_blocks );
p( 'Unused Bytes', l_unformatted_bytes );
p( 'Total Blocks', l_full_blocks);
p( 'Total bytes', l_full_bytes);

end if;

end;
/

使用方法参考:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:5350053031470

整理的DBA常用脚本

oracle用户权限检查
1. 系统权限记录在 dba_sys_privs 视图中:
select grantee, privilege, admin_option
from dba_sys_privs
where grantee = ‘USERNAME’ ;
2. 角色权限记录在 dba_role_privs 视图中:
select grantee, granted_role, admin_option
from dba_role_privs
where grantee = ‘USERNAME’ ;
3. 对象权限记录在 dba_tab_privs 视图中,虽然视图名看起来像是表权限,但是实际包含了包,存储过程等等对象级的权限:
select grantee, owner || ‘.’ || table_name obj_name, privilege, grantable
from dba_tab_privs
where grantee = ‘USERNAME’;
4. 其他还有部分权限,如表空间的quota权限,记录在 dba_ts_quota中:
select username,
tablespace_name,
bytes / 1024 / 1024 “used space (m)”,
decode(decode(max_bytes, -1, 0, max_bytes) / 1024 / 1024,
0,
‘unlimited’,
max_bytes / 1024 / 1024) “max space(m)”,
blocks used_blocks,
max_blocks
from dba_ts_quotas
where username = ‘USERNAME’;
select * from session_privs; 当前用户拥有的权限
SELECT * FROM DBA_SYS_PRIVS; 查询每个用户的权限
锁的检查
select b.owner,
b.object_name,
l.SESSION_ID,
DECODE(L.LOCKED_MODE,
0,
‘None’,
1,
‘Null’,
2,
‘Row-S (SS)’,
3,
‘Row-X (SX)’,
4,
‘Share’,
5,
‘S/Row-X (SSX)’,
6,
‘Exclusive’,
TO_CHAR(L.LOCKED_MODE)) MODE_HELD,
s.USERNAME
from dba_objects b, v$locked_object l, V$SESSION S
where b.object_id = l.object_id
and l.SESSION_ID = s.SID
查看一个长查询的进度
SELECT *
FROM ( select username,opname,sid,serial#,
context,b.sql_text,sofar,totalwork,
round(sofar/totalwork*100,2) “% Complete”,
elapsed_seconds
from v$session_longops , v$sql b
where sql_hash_value=b.hash_value
and sql_address = address
and totalwork <> 0
)
WHERE “% Complete” <> 100 ;
查看ACTIVE SESSION的等待事件
select a.event,
sum(decode(wait_Time, 0, 0, 1)) “Prev”,
sum(decode(wait_Time, 0, 1, 0)) “Curr”,
count(*) “Tot”
from v$session_wait a, v$session b
where a.sid = b.sid
and b.status = ‘ACTIVE’
group by a.event
— having count(*) > 10
order by 4;

在某个用户下找所有的索引
select user_indexes.table_name, user_indexes.index_name,uniqueness, column_name
from user_ind_columns, user_indexes
where user_ind_columns.index_name = user_indexes.index_name
and user_ind_columns.table_name = user_indexes.table_name
order by user_indexes.table_type, user_indexes.table_name,
user_indexes.index_name, column_position;
通过DBMS_METADATA包得到对象的DLL语句
a.获取单个的建表和建索引的语法,其他对象类似:
select dbms_metadata.get_ddl(‘TABLE’,’TABLE_NAME’,’TABLE_OWNER’) from dual;
select dbms_metadata.get_ddl(‘INDEX’,’INDEX_NAME’,’INDEX_OWNER’) from dual;

b.获取一个SCHEMA下的所有建表的语法,以scott为例,其他对象类似:
SELECT DBMS_METADATA.GET_DDL(‘TABLE’, u.table_name, u.owner) || ‘;’
FROM DBA_TABLES u
where owner = ‘SCOTT’ ;
查看回滚段名称及大小
select segment_name,
tablespace_name,
r.status,
(initial_extent / 1024) InitialExtent,
(next_extent / 1024) NextExtent,
max_extents,
v.curext CurExtent
From dba_rollback_segs r, v$rollstat v
Where r.segment_id = v.usn(+)
order by segment_name;

查看表空间的名称及大小
select t.tablespace_name, round(sum(bytes / (1024 * 1024)), 0) ts_size
from dba_tablespaces t, dba_data_files d
where t.tablespace_name = d.tablespace_name
group by t.tablespace_name;

查看数据库的版本
Select version
FROM Product_component_version
Where SUBSTR(PRODUCT, 1, 6) = ‘Oracle’;

查看数据库的创建日期和归档方式
Select Created, Log_Mode From V$Database;

查看还没提交的事务
select * from v$locked_object;
select * from v$transaction;
查找object为哪些进程
select p.spid,
s.sid,
s.serial# serial_num,
s.username user_name,
a.type object_type,
s.osuser os_user_name,
a.owner,
a.object object_name,
decode(sign(48 – command),
1,
to_char(command),
‘Action Code #’ || to_char(command)) action,
p.program oracle_process,
s.terminal terminal,
s.program program,
s.status session_status
from v$session s, v$access a, v$process p
where s.paddr = p.addr
and s.type = ‘USER’
and a.sid = s.sid
and a.object = ‘EMP’
order by s.username, s.osuser
怎样计算一个表占用的空间的大小?
select owner,
table_name,
NUM_ROWS,
BLOCKS * AAA / 1024 / 1024 “Size M”,
EMPTY_BLOCKS,
LAST_ANALYZED
from dba_tables
where table_name = ‘XXX’;

注意:执行以上语句前要先对表做统计分析

select sum(a.bytes) / 1024 * 1024 “size”
from dba_extents a
where a.segment_name = ‘GOV_FDDBR’
select a.bytes / 1024 * 1024 “size”, (a.blocks * 8192) / 1024 * 1024 “da”
from dba_segments a
where a.segment_name = ‘GOV_FDDBR’
如何查看最大会话数
SELECT * FROM V$PARAMETER WHERE NAME LIKE ‘proc%’;
SQL>
SQL> show parameter processes

NAME TYPE VALUE
———————————— ——- ——————————
aq_tm_processes integer 1
db_writer_processes integer 1
job_queue_processes integer 4
log_archive_max_processes integer 1
processes integer 200

这里为200个用户。

select * from v$license;
其中sessions_highwater纪录曾经到达的最大会话数
如何在Oracle服务器上通过SQLPLUS查看本机IP地址

select sys_context(‘userenv’,’ip_address’) from dual;

如何将表、索引移动表空间
ALTER TABLE TABLE_NAME MOVE TABLESPACE_NAME;
ALTER INDEX INDEX_NAME REBUILD TABLESPACE TABLESPACE_NAME;
如何才能得知系统当前的SCN号
select max(ktuxescnw * power(2, 32) + ktuxescnb) from x$ktuxe;
如何在字符串里加回车
select ‘Welcome to visit’||chr(10)||’www.CSDN.NET’ from dual;
如何将小表放入keep池中
alter table xxx storage(buffer_pool keep);
如何查询做比较大的排序的进程?
SELECT b.tablespace,
b.segfile#,
b.segblk#,
b.blocks,
a.sid,
a.serial#,
¡¡ a.username,
a.osuser,
a.status ¡¡
FROM v$session a, v$sort_usage b ¡¡
WHERE a.saddr = b.session_addr ¡¡
ORDER BY b.tablespace, b.segfile#, b.segblk#, b.blocks;

如何删除重复记录?
DELETE FROM TABLE_NAME
WHERE ROWID != (SELECT MAX(ROWID)
FROM TABLE_NAME D
WHERE TABLE_NAME.COL1 = D.COL1
AND TABLE_NAME.COL2 = D.COL2);
如何回滚段的争用情况
select name, waits, gets, waits / gets “Ratio”  
from v$rollstat C, v$rollname D  
where C.usn = D.usn;
如何监控表空间的 I/O 比例
select B.tablespace_name name,
B.file_name “file”,
A.phyrds pyr,
  A.phyblkrd pbr,
A.phywrts pyw,
A.phyblkwrt pbw  
from v$filestat A, dba_data_files B  
where A.file# = B.file_id  
order by B.tablespace_name;

如何监控文件系统的 I/O 比例
Select substr(C.file#, 1, 2) “#”,
substr(C.name, 1, 30) “Name”,
C.status,
C.bytes,
D.phyrds,
D.phywrts  
from v$datafile C, v$filestat D  
where C.file# = D.file#;
如何在某个用户下找所有的索引
select user_indexes.table_name,
user_indexes.index_name,
uniqueness,
column_name  
from user_ind_columns, user_indexes  
where user_ind_columns.index_name = user_indexes.index_name
and user_ind_columns.table_name = user_indexes.table_name  
order by user_indexes.table_type,
user_indexes.table_name,
 user_indexes.index_name,
column_position;
如何监控 SGA 中字典缓冲区的命中率
select parameter,
gets,
Getmisses,
getmisses / (gets + getmisses) * 100 “miss ratio”,
 (1 – (sum(getmisses) / (sum(gets) + sum(getmisses)))) * 100 “Hit ratio”  
from v$rowcache  
where gets + getmisses <> 0  
group by parameter, gets, getmisses;
如何监控 SGA 中共享缓存区的命中率,应该小于1%
select sum(pins) “Total Pins”,
sum(reloads) “Total Reloads”,
 sum(reloads) / sum(pins) * 100 libcache  
from v$librarycache;

select sum(pinhits – reloads) / sum(pins) “hit radio”,
sum(reloads) / sum(pins) ¡¡¡¡”reload percent” ¡¡
from v$librarycache;
监控 SGA 中重做日志缓存区的命中率,应该小于1%
SELECT name,
gets,
misses,
immediate_gets,
immediate_misses,
Decode(gets, 0, 0, misses / gets * 100) ratio1,
Decode(immediate_gets+immediate_misses,0,0, immediate_misses / (immediate_gets + immediate_misses) * 100) ratio2  
FROM v$latch
WHERE name IN (‘redo allocation’, ‘redo copy’);

监控内存和硬盘的排序比率,最好使它小于 .10,增加 sort_area_size
SELECT name, value
FROM v$sysstat
WHERE name IN (‘sorts (memory)’, ‘sorts(disk)’);
如何监控当前数据库谁在运行什幺SQL语句?
SELECT osuser, username, sql_text
from v$session a, v$sqltext b  
where a.sql_address = b.address
order by address, piece;
如何查看碎片程度高的表?
SELECT segment_name table_name, COUNT(*) extents  
FROM dba_segments
WHERE owner NOT IN (‘SYS’, ‘SYSTEM’)
GROUP BY segment_name  
HAVING COUNT(*) = (SELECT MAX(COUNT(*))
FROM dba_segments
GROUP BY segment_name);
如何知道表在表空间中的存储情况?
select segment_name, sum(bytes), count(*) ext_quan
from dba_extents
where tablespace_name = ‘&tablespace_name’
and segment_type = ‘TABLE’
group by tablespace_name, segment_name;
如何知道索引在表空间中的存储情况?
select segment_name, count(*)
from dba_extents
where segment_type = ‘INDEX’
and owner = ‘&owner’  
group by segment_name;

如何知道使用CPU多的用户session?
Select a.sid,spid,status,
substr(a.program,1,40)
prog,a.terminal,osuser,value/60/100 value
  from v$session a,v$process b,v$sesstat c
  where c.statistic#=11 and c.sid=a.sid and a.paddr=b.addr
order by value desc;
物理读和内存读较高SQL
SELECT t.HASH_VALUE,
t.EXECUTIONS,
t.DISK_READS,
round(t.DISK_READS / t.EXECUTIONS) AS perDiskReads,
t.BUFFER_GETS,
round(t.BUFFER_GETS / t.EXECUTIONS) AS perBufferReads,
t.ELAPSED_TIME,
round(t.ELAPSED_TIME / t.EXECUTIONS) AS perElayTime,
t.CPU_TIME,
round(t.CPU_TIME / t.EXECUTIONS) AS perCpuTime,
t.FIRST_LOAD_TIME,
t.SQL_TEXT
FROM v$sql t
WHERE (t.DISK_READS / t.EXECUTIONS > 500 OR
t.BUFFER_GETS / t.EXECUTIONS > 20000)
AND t.EXECUTIONS > 0
ORDER BY 6 DESC;
查看低效率的SQL语句
SELECT EXECUTIONS,
DISK_READS,
BUFFER_GETS,
ROUND((BUFFER_GETS – DISK_READS) / BUFFER_GETS, 2) Hit_radio,
ROUND(DISK_READS / EXECUTIONS, 2) Reads_per_run,
SQL_TEXT
FROM  V$SQLAREA    
WHERE EXECUTIONS > 0   
AND  BUFFER_GETS > 0   
AND (BUFFER_GETS – DISK_READS) / BUFFER_GETS < 0.8    ORDER BY EXECUTIONS DESC 或者 select executions exec, loads loads, parse_calls parse, disk_reads reads, buffer_gets gets, rows_processed rows_proc, sorts sorts, sql_text from v$sqlarea order by &sortkey desc; 找出oracle中从没有使用的索引 set pages 999; set heading off; spool run_monitor.sql select 'alter index '||owner||'.'||index_name||' monitoring usage;' from dba_indexes where owner not in ('SYS','SYSTEM','PERFSTAT') spool off; @run_monitor 等待一段时间直到在数据库上运行了足够多的SQL语句以后,然后你就可以查询新的V$OBJECT_USAGE视图。 Select index_name,table_name,mon,used from v$object_usage; 在V$OBJECT_USAGE有一列被称作USED,它的值是YES或者NO。不幸的是,它不会告诉你Oracle使用了这个索引多少次,但是这个工具对于找出没有使用的索引还是很有用的。 自己编写的脚本 select c.SID,c.STATUS,s.NAME,b.VALUE from v$statname s, v$sesstat b, v$session c where s.STATISTIC# = b.STATISTIC# and b.SID = c.SID and b.sid=&sid and s.NAME in ('consistent gets','physical reads','parse count (total)','parse count (hard)') V$sql:查询一条sql执行时间及消耗的cpu时间,被执行及被分析的次数 Parse_calls, Executions Cpu_time, Elapsed_time Alter system flush shared_pool 清空共享池