oracle优化常用经典参考

2-调优步骤:  

设计调优 

应用调优 程序员代码

内存

连接

操作系统

2-已有产品的调优

 1 定位问题

 2 查看操作系统和oracle统计

 3 考虑通用系统错误

 4 假定问题

 5 通过参数修改去调优

 

3调优方法

 1 检查日志和trace  file

 2 检查参数文件

检查 内存 cpu

那些sql占用cpuio

如果相应时间慢;

 1分析工作实现和相应时间

检查那部分时间长

细化问题

 

 

查看alert  log

 1 查看位置

Show parameter dump

Name 是 backgroup_dump_dest 所对应的目录是alert log所在的目录

检查文件

  1 检查 错误是 ORA 的错误和快损坏错误

  2 分析这个文件

  3 定期移动和清空错误文件

     清空文件: cat  /dev/null  >文件名

 

 

 

改变系统值

 Alter system set 参数名=参数值 scope=  both 或 spfile 

 Both 代表同时改变内存和文件 

 

查看user trace file(用户操作日志文件)

Show parameter dump

Name 是 user_dump_dest 所对应的目录是user trace file所在的目录

产生trace文件的方法:

  1 修改自己的sessionalter  session set sql _trace=true

  2 使用sys用户登录,调用存储过程:将某个用户的session 产生trace文件

 



 

  3 sql_trace系统参数确定系统中的所有用户产生日志

5-dba的视图

 dba_tables,dba_tab_colums,dba_indexes,index_stats

 

重要的动态视图

系统相关视图

V$sysstat 系统统计

V$sgastat SGA统计

V$system_event 系统事件 事件名 v$event_name

 


session 相关的视图

 

 

v$sesstat session统计数据

v$sesstat_event 

重要视图

 

 

 

 

 

 

数据库设计

不同用途的数据放在不同的tablespace避免资源争用

不同的tablespace放在不同的物理驱动器调高I/O并发能力

日志文件放在速度快的磁盘上,数据文件可以放在速度慢的磁盘上

日志文件的同组中不同成员放在不同的物理磁盘

 

 

7通过物理文件的读写次数来调优

 

Select d.tablespace_name,d.file_name,f.phyrds,f.phywrts from v$filestat f,dba_data_files d where f.file#=d.file_id;

可以通过设置Oracle读写块的大小提高I/O效率

参数如下:

DB_FILE_MULTIBLOCK_READ_COUNT

 

8 striping(均匀分布数据)

 1 操作系统或文件系统支持striping

建表或更改表时使用 allocate 可以达到striping的目的

8 DB_FILE_MULTIBLOCK_READ_COUNT

可以通过设置Oracle读写块的大小提高I/O效率

 

大于6秒的操作查询

 V$session_longops

Select  name,value from v$sysstat where nane like ‘ %table scan%’

监控全表扫描

 

 

3监控大表运行情况

大于6秒的全表扫描记录在

v$session_longops

查看全表扫描的记录条数

 

Show parameter log_ch

 

9 Oracle启动时间

通过调整 FAST_START_MTTR_TARGET保证Oracle启动时间,Oracle可以根据这个参数调整其他参数

 

9重做日志文件

 如果没有足够重做日志文件,就会造成系统阻塞,

 

 

解决办法:

     

加大重做日志文件

增加归档进程

    设置参数:LOG_ARCHIVE_MAX_PROCESSES

   在alert log中出现如下错误说明日志文件已经写满

 

通过:

V$log_file

V$log

提高sql命中

11查询系统hard parse的次数

 

V$sysstat 表中的 parse count hard)是解析sql条数

11 提高sql相似sql在共享池中的命中率

 

12 使用绑定变量提高共享sql

   使用preparedStatement

 

13 查看共享池信息

 

 

13查看v$sgastat中的free memory决定是否要扩大共享内存

13 查看执行少于5次的sql通过查看解析次数与执行次数找到效率低的原因

 select sql_text from v$sqlarea where executions<5 order by upper(sql_text)

13 查看sql查看解析次数与执行次数找到效率低的原因

 select sql_text, parse_calls,executions from v$sqlarea 

14 存储过程的调用着是过程的属主,不是调用者

14 sql中添加表的用户可以减少访问数据字典的次数

14 在业务高发期使用ddl语句会降低sql的命中,因为sql需要重新解析

14 在业务高发期V$librarycache 中的reloadsinvalidations要尽可能小,如果reloads太大说明shared pool太小

14 查看sql命中率:

Select gethitratio from v$librarycache where namespace=’SQL AREA’

调整shared pool

14查看那些sql正在执行:

Select sql_text,users_executing from v$sqlarea

 

15 查看v$share_pool_advice由Oracle提供共享池优化参数

 

16 使用下面的sql 估算共享内存

 

将以上两项值相加基本就是估算的librarycache 的内存大小

查看共享池信息

Show parameter shared

16 设置保留池的大小,以满足大对象和临时对象的使用

Shared_pool_reserved_size

 

   Request_failures持续太大说明保留池太小

   需要加大保留池和共享池

 

16调整共享池大小

  Shared_pool_size

  不能最大值取决于操作系统的内存

不能太小

 

17 在共享区,一直保留在内存区,不参与内存淘汰算法

 

清除shared pool

Alter system flush shared_pool

18 查询匿名块

 

 

 

18 调整Data Dictionary cache

通过v$rowcache

 

 

    调整共享池来调整DD cache

11 large pool

 

Large_pool_size

 Show parameter size

 

 

 

19Buffer cache 调优

 

 1 降低sql读入buffer数据

增大buffer cache

 

 

 

Free buffer inspected :找到空闲块之前做的消耗

Free buffer waits 没有可用的空闲块

Buffer busy waits 块被占用

 

21 查询等待的事件及等待块信息

 

 

21 计算命中率

 

 

 

大表多次扫描会降低命中率

好的命中率:命中率高,坏事件少

将常用的数据放在中间件层,减轻数据库压力

Cache使用

23增大cache_size

 

增大cache之前

没有3中事件

优化了sql

防止操作系统将sga放到os的交换区

命中率低

使用

 增加db_cache_size

 

增加时这个只不能大于sqa_size

 

 

 

23 Oracle 9i 有三中pool

Reclye pool

Keep pool

Default pool

  三个buffer pool大小不一样,算法一样,可以利用这一特性决定吧对象放在那个pool

 

使用办法:

热块放在 default pool

温块放在 keep pool

冷快放在 recycle pool

 

 

23放对象放在pool中的语法:

 

 

 

24查看对象使用的块

 

 

 

 

 

 

24计算命pool中率:

 

 

 

 

 

24创建cache 

 方法一:创建表时

 

 

方法2:修改普通表到cache 

方法3:查询后放在cache

 

 

25自动管理内存

 

25配置多个DBWn

  Alter system db_writer_precesses //操作系统必须支持异步I/O,多cpu使用

  

 

开启异步I/O 

在不支持异步I/O的情况下,修改dbwr_io_slaves数量也可以达到增加DBWn的效果

 

 

 

27LGWR是使性能下将

 

Redo Entries 存在的记录数:

Redo buffer allocation retries: 申请redo buffer 的次数,此值过大说明 redo buffer 太小

 

28当发生下列事件时会引起性能下降

  1 日志文件交换

 

   增大redo log files

  2 检查点未完成

 

 

 

 

解决办法:

a设置Fast_start_mttr_target越小增加checkPoint的次数

增加redo log 组和成员

 

归档引起

 

 

解决办法:


增加redo log 组和成员

2  archive文件太多,没地方写归档文件,可以删除文件

增加归档进程 log_archive_max_proceses

 

28加速数据插入的时间:

 使用无log方式,批量插入数据

 

 

共享服务器

 

 

 

 

 

 

 

 

 

 

优化排序

 

32优化排序-自动管理PGA

设置自动管理PGAwork_size_policy = auto 

在自动管理PAG模式下设置PAG大小:pga_aggregate_target 

 

 

 

 

32设置PGA建议:

 

 

32设置PGA的例子

 

32 oracle的内存设置:

Oracle的内存由SGAPGA 之和 决定

 

 

 

 

Over allocation count增大说明 aggregate pga target 太小

 

 

34 查询建议的PGA内存

 

 

Select round(pga_target_for_estimate/1024/1024) as target_mb,round(BYTES_PROCESSED/1024/1024) as process_mb,ESTD_PGA_CACHE_HIT_PERCENTAGE hit_ratio,ESTD_OVERALLOC_COUNT from v$pga_target_advice;

 

34 查看 sesstat

 

35单个用户的排序内存

 

 

36 统计排序

 

 

 

36避免排序:

 

36当磁盘排序/内存排序比值大于5%,需要增大排序内存

 

 

 

Sql调优

42 设置sql优化模式

 

Choose9i的默认值

All_rows:最大吞吐率 11的默认值

First_rows_n:最快相应时间,可以设定

First_rows: 10g后不要用

43稳定执行计划

 Optimizer_features_enable=数据库版本号

44 获得sql 的执行计划

创建plan

 @/目录/ultxplan.sql

@?代表oracle home目录

获得

 

查看执行计划

 A Select * from table_plan

B select * from table(dbms_xplan.display); 

44 生成trace文件及查看

开启trace功能

 

使用tkprof格式化文件

 

 

44 自动trace

创建table_plan

@/目录/ultxplan.sql

@?代表oracle home目录

2创建同义词并授权

 

执行脚本、授权

 

设置自动trace,并得到结果

 

 

统计信息

47获得表的统计信息

获得对象id

 

 

获得表的统计信息

 

 

 

 

 

52 查询表块使用情况

分析表

 

查看表

 

52扩展和取消块

 

 

 

 

 

 

 

 

 

 

OLTP系统使用小块4k8k

OLAP系统使用16k64k

 

索引管理

 

54 监控索引空间

 

Rebuild:会重建索引 ,代价高

Coalesce:修补索引

 

54查看索引使用情况:

查询表object_usage


 

 

 

Oracle数据块架构

55创建集群表:

将两张表放在一个segment

 

58创建索引集群表:

 

创建集群

Create cluster mycluster (deptno number(2)) size 1024

Deptno 集群的key

1024 一个block的大小,决定可以放几条记录。

默认是放一条记录

 

创建索引


 

 

 

 

 

 

59分区表

时间分区表:

 

 

 

 

 

 

 

 

 

Hash分区表

 

 

 

 

应用调优

 

60压缩索引

压缩索引可以提高索引的查询效率,节约空间

 

62创建索引表:

   当创建的索引和表的容量一样时。就直接创建索引表比以往的方案要好。

  索引表没有rowid

 

 

 

 

Index_stats索引的的信息

 

 

 

 

创建倒序索引:

 

 

 

Bitmap索引在大表,只读表,重复字段多,较好,维护较难

 

 

 

 

给索引表建逻辑rowid使用下列语法:

 

 

66 query rewrite

 

 

 

 

 

 

68 锁相关视图

 

 

 

 

 

69 手动锁表

 

Statspack

安装schema

产看说明文档:

$oracle_home/rdbms/admin/Spdoc.Txt

创建表空间

 

3执行脚本

创建脚本;

 

 

删除的脚本:错误可以先删除

 

 

 

通过sprepcon.Sql修改参数

 

 

 

 

查看oracle缓存的命中率(大于90%) 

select 1 - ((physical.value - direct.value - lobs.value) / logical.value) 

"Buffer Cache Hit Ratio" 

from v$sysstat physical,v$sysstat direct,v$sysstat lobs,v$sysstat logical 

where physical.name = 'physical reads' 

and direct.name='physical reads direct' 

and lobs.name='physical reads direct (lob)' 

and logical.name='session logical reads'; 

 

查询文件信息:select * from  dba_data_files

 

 

 

 

 

 

 

oracle redo log管理:

1.  组成员要分散,磁盘IO要快

 

2.  日志文件大小分配要合理

 

保证每个组的切换时间应该不小于20分钟左右

 

切换日志:

 

Alter system  switch logfile;

 

添加日志组:

 

alter database add logfile group 4 '/u01/oracle/oradata/orcl/redo04.log' size 50m;

 

下次切换日志会优先使用此文件

 

其中group 4 可以省略不写,系统会自动分配

 

 

 

 

 

 

 

添加有多个成员的组:

 

 

 

alter database add logfile ('/u01/oracle/oradata/orcl/redo06.log','/u01/oracle/oradata/orcl/redo6.log') size 50m;

 

 

 

往已经有的组里添加成员:

 

alter database add logfile member '/u01/oracle/oradata/orcl/redo4.log' to group 4;

 

大小默认是组内已有成员的大小。

 

alter database add logfile member '

 

删除日志组:

 

日志组状态不能使currentactive

 

alter database drop logfile group 6,group 5

 

 

 

删除某个成员:

 

alter database drop logfile member '

 

 

 

重做日志的重命名:

 

在mountopen阶段才能更改,因为是改到控制文件里面了。

 

日志文件不能是currentactive

 

先把文件拷贝到另一个名称

 

Ho cp  

 

Alter datebase  rename file ‘’ to ‘’

 

非归档模式可以直接改随便哪个状态都可但不能使current

 

 

 

Current active丢失后数据库启动会成问题

 

 

 

改变日志组的大小:(先把原来的组删除,在新建同名的组)

 

Alter database drop logfile group 3;

 

Alter database add logfile group 3 (‘/u01/oracle/oradata/orcl/redo03.log’,’ /u01/oracle/oradata/orcl/redo03.log’);

 

 

 

监控日志组自动切换的时间间隔:

 

Select  to_char(first_time,’yyyy-mm-dd hh24:mi:ss’’),group# from v$log;

 

 

 

日志文件需要监视内容:

 

1.       位置在哪里,是否存在

 

2.       磁盘空间是否足够

 

3.       日志切换间隔时间

 

4.       看日志组下是否具有多个成员

 

5.       不一致

 

日志不一致的处理方法:

 

清空日志:Alter  database clear logfile group n; 清空非current active的日志

 

Alter database clear unarchived logfile group n; 清空非current的日志;

 

 

 

日志文件全部丢失:

 

归档模式下不使用隐藏参数:

 

Recover database using backup controlfile;

 

Alter database open resetlogs;

 

使用隐藏参数方法:

 

SQL> alter system set "_allow_resetlogs_corruption"=true scope=spfile;

 

Startup  force mount

 

 

 

Alter database open resetlogs

 

 

 

重置隐藏参数(要不容易引起错误)

 

Alter  system reset  "_allow_resetlogs_corruption" scope =spfile sid =’*’;

 

 

 

create spfile from pfile='/home/oracle/spfileFLT.ora';

 

 

startup pfile='/home/oracle/spfileFLT.ora';

create spfile='/orac/orahome/10.2.0/dbs/spfileFLT1.ora' from pfile='/orac/orahome/admin/FLT/pfile/init.ora.2302013164056';

 

 

调优

判断回滚段竞争的SQL语句:(当Ratio大于2时存在回滚段竞争,需要增加更多的回滚段)

 

select rn.name, rs.GETS, rs.WAITS, (rs.WAITS / rs.GETS) * 100 ratio

from v$rollstat rs, v$rollname rn

where rs.USN = rn.usn

 

判断恢复日志竞争的SQL语句:(immediate_contentionwait_contention的值大于1时存在竞争)

select name,

(t.IMMEDIATE_MISSES /

decode((t.IMMEDIATE_GETS + t.IMMEDIATE_MISSES),

0,

-1,

(t.IMMEDIATE_GETS + t.IMMEDIATE_MISSES))) * 100 immediate_contention,

(t.MISSES / decode((t.GETS + t.MISSES), 0, -1, (t.GETS + t.MISSES))) * 100 wait_contention

from v$latch t

where name in ('redo copy', 'redo allocation')

 

 

判断表空间碎片:(如果最大空闲空间占总空间很大比例则可能不存在碎片,如果比例较小,且有许多空闲空间,则可能碎片很多)

select t.tablespace_name,

sum(t.bytes),

max(t.bytes),

count(*),

max(t.bytes) / sum(t.bytes) radio

from dba_free_space t

group by t.tablespace_name

order by t.tablespace_name

确定命中排序域的次数:

select t.NAME, t.VALUE from v$sysstat t where t.NAME like 'sort%'

查看当前SGA值:

select * from v$sga

确定高速缓冲区命中率:(如果命中率低于70%,则应该加大init.ora参数中的DB_BLOCK_BUFFER的值)

select 1 - sum(decode(name, 'physical reads', value, 0)) /

(sum(decode(name, 'db block gets', value, 0)) +

sum(decode(name, 'consistent gets', value, 0))) hit_ratio

from v$sysstat t

where name in ('physical reads', 'db block gets', 'consistent gets')

确定共享池中的命中率:(如果ratio1大于1时,需要加大共享池,如果ratio2大于10%时,需要加大共享池SHARED_POOL_SIZE

select sum(pins) pins,

sum(reloads) reloads,

(sum(reloads) / sum(pins)) * 100 ratio1

from v$librarycache

select sum(gets) gets,

sum(getmisses) getmisses,

(sum(getmisses) / sum(gets)) * 100 ratio2

from v$rowcache

查询INIT.ORA参数:

select * from v$parameter

/

Oracle性能参数查看(转)

0、数据库参数属性

col PROPERTY_NAME format a25

col PROPERTY_VALUE format a30

col DESCRIPTION format a100

select * from database_properties;

select * from v$version;

1、求当前会话的SIDSERIAL#

SELECT Sid, Serial# FROM V$session

WHERE Audsid = Sys_Context('USERENV', 'SESSIONID');

2、查询sessionOS进程ID

SELECT p.Spid "OS Thread", b.NAME "Name-User", s.Program, s.Sid, s.Serial#,s.Osuser, s.Machine

FROM V$process p, V$session s, V$bgprocess b

WHERE p.Addr = s.Paddr

AND p.Addr = b.Paddr And (s.sid=&1 or p.spid=&1)

UNION ALL

SELECT p.Spid "OS Thread", s.Username "Name-User", s.Program, s.Sid,s.Serial#, s.Osuser, s.Machine

FROM V$process p, V$session s

WHERE p.Addr = s.Paddr

And (s.sid=&1 or p.spid=&1)

AND s.Username IS NOT NULL;

3、根据sid查看对应连接正在运行的sql 

SELECT /*+ PUSH_SUBQ */ Command_Type, Sql_Text, Sharable_Mem, Persistent_Mem, Runtime_Mem, Sorts,

Version_Count, Loaded_Versions, Open_Versions, Users_Opening, Executions,

Users_Executing, Loads, First_Load_Time, Invalidations, Parse_Calls,

Disk_Reads, Buffer_Gets, Rows_Processed, SYSDATE Start_Time,

SYSDATE Finish_Time, '>' || Address Sql_Address, 'N' Status

FROM V$sqlarea WHERE Address = (SELECT Sql_Address

FROM V$session WHERE Sid = &sid );

4、查找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 = '&obj'

ORDER BY s.Username, s.Osuser

5、查看有哪些用户连接

SELECT s.Osuser Os_User_Name,Decode(Sign(48 - Command),1,To_Char(Command),

'Action Code #' || To_Char(Command)) Action,

p.Program Oracle_Process, Status Session_Status, s.Terminal Terminal,

s.Program Program, s.Username User_Name,

s.Fixed_Table_Sequence Activity_Meter, '' Query, 0 Memory,

0 Max_Memory, 0 Cpu_Usage, s.Sid, s.Serial# Serial_Num

FROM V$session s, V$process p

WHERE s.Paddr = p.Addr

AND s.TYPE = 'USER'

ORDER BY s.Username, s.Osuser

6、根据v.sid查看对应连接的资源占用等情况

SELECT n.NAME, v.VALUE, n.CLASS, n.Statistic# FROM V$statname n, V$sesstat v

WHERE v.Sid = &sid

AND v.Statistic# = n.Statistic#

ORDER BY n.CLASS, n.Statistic#

7、查询耗资源的进程(top session

SELECT s.Schemaname Schema_Name,Decode(Sign(48 - Command),

1, To_Char(Command), 'Action Code #' || To_Char(Command)) Action,Status Session_Status, s.Osuser Os_User_Name, s.Sid, p.Spid,s.Serial# Serial_Num, Nvl(s.Username, '[Oracle process]') User_Name,

s.Terminal Terminal, s.Program Program, St.VALUE Criteria_Value

FROM V$sesstat St, V$session s, V$process p

WHERE St.Sid = s.Sid

AND St.Statistic# = To_Number('38')

AND ('ALL' = 'ALL' OR s.Status = 'ALL')

AND p.Addr = s.Paddr

ORDER BY St.VALUE DESC, p.Spid ASC, s.Username ASC, s.Osuser ASC

8、查看锁(lock)情况

SELECT /*+ RULE */ Ls.Osuser Os_User_Name, Ls.Username User_Name,Decode(Ls.TYPE,

'RW', 'Row wait enqueue lock', 'TM', 'DML enqueue lock','TX', 'Transaction enqueue lock', 'UL', 'User supplied lock') Lock_Type,o.Object_Name OBJECT,Decode(Ls.Lmode,1, NULL, 2, 'Row Share', 3, 'Row Exclusive',

4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive',NULL) Lock_Mode,o.Owner, Ls.Sid, Ls.Serial# Serial_Num, Ls.Id1, Ls.Id2 FROM Sys.Dba_Objects o, 

(SELECT s.Osuser, s.Username, l.TYPE, l.Lmode, s.Sid, s.Serial#, l.Id1,l.Id2 FROM V$session s, V$lock l

WHERE s.Sid = l.Sid) Ls

WHERE o.Object_Id = Ls.Id1

AND o.Owner <> 'SYS'

ORDER BY o.Owner, o.Object_Name;

9、查看等待(wait)情况

SELECT Ws.CLASS, Ws.COUNT COUNT, SUM(Ss.VALUE) Sum_Value

FROM V$waitstat Ws, V$sysstat Ss

WHERE Ss.NAME IN ('db block gets', 'consistent gets')

GROUP BY Ws.CLASS, Ws.COUNT;

10、求process/session的状态

SELECT p.Pid, p.Spid, s.Program, s.Sid, s.Serial#

FROM V$process p, V$session s

WHERE s.Paddr = p.Addr;

11、求谁阻塞了某个session(10g)

SELECT Sid, Username, Event, Blocking_Session, Seconds_In_Wait, Wait_Time

FROM V$session

WHERE State IN ('WAITING')

AND Wait_Class != 'Idle';

12、查会话的阻塞

col user_name format a32

SELECT /*+ rule */ Lpad(' ', Decode(l.Xidusn, 0, 3, 0)) || l.Oracle_Username User_Name,

o.Owner, o.Object_Name, s.Sid, s.Serial#

FROM V$locked_Object l, Dba_Objects o, V$session s

WHERE l.Object_Id = o.Object_Id

AND l.Session_Id = s.Sid

ORDER BY o.Object_Id, Xidusn DESC;

col username format a15

col lock_level format a8

col owner format a18

col object_name format a32

SELECT /*+ rule */ s.Username,Decode(l.TYPE, 'tm', 'table lock', 'tx', 'row lock', NULL) Lock_Level,

o.Owner, o.Object_Name, s.Sid, s.Serial#

FROM V$session s, V$lock l, Dba_Objects o

WHERE l.Sid = s.Sid

AND l.Id1 = o.Object_Id(+)

AND s.Username IS NOT NULL;

13、求等待的事件及会话信息/求会话的等待及会话信息

SELECT Se.Sid, s.Username, Se.Event, Se.Total_Waits, Se.Time_Waited,Se.Average_Wait

FROM V$session s, V$session_Event Se

WHERE s.Username IS NOT NULL

AND Se.Sid = s.Sid

AND s.Status = 'ACTIVE'

AND Se.Event NOT LIKE '%SQL*Net%'

ORDER BY s.Username;

SELECT s.Sid, s.Username, Sw.Event, Sw.Wait_Time, Sw.State,Sw.Seconds_In_Wait

FROM V$session s, V$session_Wait Sw

WHERE s.Username IS NOT NULL

AND Sw.Sid = s.Sid

AND Sw.Event NOT LIKE '%SQL*Net%'

ORDER BY s.Username;

14、求会话等待的file_id/block_id

col event format a24

col p1text format a12

col p2text format a12

col p3text format a12

SELECT Sid, Event, P1text, P1, P2text, P2, P3text, P3

FROM V$session_Wait

WHERE Event NOT LIKE '%SQL%'

AND Event NOT LIKE '%rdbms%'

AND Event NOT LIKE '%mon%'

ORDER BY Event;

SELECT NAME, Wait_Time

FROM V$latch l

WHERE EXISTS (SELECT 1

FROM (SELECT Sid, Event, P1text, P1, P2text, P2, P3text, P3

FROM V$session_Wait

WHERE Event NOT LIKE '%SQL%'

AND Event NOT LIKE '%rdbms%'

AND Event NOT LIKE '%mon%') x

WHERE x.P1 = l.Latch#);

15、求会话等待的对象

col owner format a18

col segment_name format a32

col segment_type format a32

SELECT Owner, Segment_Name, Segment_Type

FROM Dba_Extents

WHERE File_Id = &File_Id

AND &Block_Id BETWEEN Block_Id AND Block_Id + Blocks - 1;

16、求出某个进程,并对它进行跟踪

SELECT s.Sid, s.Serial#

FROM V$session s, V$process p

WHERE s.Paddr = p.Addr

AND p.Spid = &1;

Exec Dbms_System.Set_Sql_Trace_In_Session(&1, &2, TRUE);

Exec Dbms_System.Set_Sql_Trace_In_Session(&1, &2, FALSE);

17、求当前session的跟踪文件

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 = 'instance_name'

AND p.Addr = s.Paddr

AND s.Audsid = Userenv('SESSIONID')

AND p.Background IS NULL

AND Instr(p.Program, 'CJQ') = 0;

18、求出锁定的对象

SELECT Do.Object_Name, Session_Id, Process, Locked_Mode

FROM V$locked_Object Lo, Dba_Objects Do

WHERE Lo.Object_Id = Do.Object_Id;

19DB_Cache建议

SELECT size_for_estimate, buffers_for_estimate, estd_physical_read_factor, estd_physical_reads

FROM V$DB_CACHE_ADVICE

WHERE name = 'DEFAULT'

AND block_size = (SELECT value FROM V$PARAMETER WHERE name = 'db_block_size')

AND advice_status = 'ON';

20、查看各项SGA相关参数:SGASGASTAT

select substr(name,1,10) name,substr(value,1,10) value 

from v$parameter where name = 'log_buffer';

select * from v$sgastat ;

select * from v$sga;

show parameters area_size   #查看 各项区域内存参数, 其中sort_area为排序参数用;

 

各项视图建议参数值:V$DB_CACHE_ADVICEV$SHARED_POOL_ADVICE),关于PGA

也有相关视图V$PGA_TARGET_ADVICE 等。

21、内存使用锁定在物理内存:

AIX 5LAIX 4.3.3 以上)

logon aix as root

cd /usr/samples/kernel

./vmtune (信息如下) v_pingshm已经是1

./vmtune -S 1

然后oracle用户修改initSID.ora 中 lock_sga = true

重新启动数据库

HP UNIX

Root身份登陆

Create the file "/etc/privgroup": vi /etc/privgroup

Add line "dba MLOCK" to file

As root, run the command "/etc/setprivgrp -f /etc/privgroup":

$/etc/setprivgrp -f /etc/privgroup

oracle用户修改initSID.oralock_sga=true

重新启动数据库

SOLARIS (solaris2.6以上)

8i版本以上数据库默认使用隐藏参数 use_ism = true ,自动锁定SGA于内存中,不用设置

lock_sga, 如果设置 lock_sga =true 使用非 root 用户启动数据库将返回错误。

WINDOWS (作用不大)

不能设置lock_sga=true,可以通过设置pre_page_sga=true,使得数据库启动的时候就把所有内

存页装载,这样可能起到一定的作用。

22、内存参数调整

数据缓冲区命中率

select value from v$sysstat where name ='physical reads';

select value from v$sysstat where name ='physical reads direct';

select value from v$sysstat where name ='physical reads direct (lob)';

select value from v$sysstat where name ='consistent gets';

select value from v$sysstat where name = 'db block gets';

这里命中率的计算应该是

令 x = physical reads direct + physical reads direct (lob)

命中率 =100 - ( physical reads - x) / (consistent gets + db block gets - x)*100

通常如果发现命中率低于90%,则应该调整应用可可以考虑是否增大数据缓冲区;

共享池的命中率

select sum(pinhits)/sum(pins)*100 "hit radio" from v$librarycache;

假如共享池的命中率低于95%,就要考虑调整应用(通常是没使用bind var )或者增加内存;

关于排序部分

select name,value from v$sysstat where name like '%sort%';

假如我们发现sorts (disk)/ (sorts (memory)+ sorts (disk))的比例过高,则通常意味着

sort_area_size 部分内存较小,可考虑调整相应的参数。

关于log_buffer

select name,value from v$sysstat

where name in('redo entries','redo buffer allocation retries');

假如 redo buffer allocation retries/ redo entries 的比例超过1%我们就可以考虑增大log_buffer

 

/

July 28

oracle 常用SQL查询

 

1、查看表空间的名称及大小

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;

 

2、查看表空间物理文件的名称及大小

select tablespace_name, file_id, file_name,

round(bytes/(1024*1024),0) total_space

from dba_data_files

order by tablespace_name;

 

 

3、查看回滚段名称及大小

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 ;

 

 

4、查看控制文件

select name from v$controlfile;

 

5、查看日志文件

select member from v$logfile;

 

 

6、查看表空间的使用情况

select sum(bytes)/(1024*1024) as free_space,tablespace_name

from dba_free_space

group by tablespace_name;

SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE,

(B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE"

FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C

WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME;

 

7、查看数据库库对象

select owner, object_type, status, count(*) count# from all_objects group by owner, object_type, status;

 

8、查看数据库的版本 

Select version FROM Product_component_version

Where SUBSTR(PRODUCT,1,6)='Oracle';

 

9、查看数据库的创建日期和归档方式

Select Created, Log_Mode, Log_Mode From V$Database;

 

10、捕捉运行很久的SQL

column username format a12

column opname format a16

column progress format a8

select username,sid,opname,

round(sofar*100 / totalwork,0) || '%' as progress,

time_remaining,sql_text

from v$session_longops , v$sql

where time_remaining <> 0

and sql_address = address

and sql_hash_value = hash_value

/

 

11。查看数据表的参数信息

SELECT partition_name, high_value, high_value_length, tablespace_name,

pct_free, pct_used, ini_trans, max_trans, initial_extent,

next_extent, min_extent, max_extent, pct_increase, FREELISTS,

freelist_groups, LOGGING, BUFFER_POOL, num_rows, blocks,

empty_blocks, avg_space, chain_cnt, avg_row_len, sample_size,

last_analyzed

FROM dba_tab_partitions

--WHERE table_name = :tname AND table_owner = :towner

ORDER BY partition_position

 

12.查看还没提交的事务

select * from v$locked_object;

select * from v$transaction;

13。查找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='SUBSCRIBER_ATTR'

order by s.username, s.osuser

 

 

14。回滚段查看

select rownum, sys.dba_rollback_segs.segment_name Name, v$rollstat.extents

Extents, v$rollstat.rssize Size_in_Bytes, v$rollstat.xacts XActs,

v$rollstat.gets Gets, v$rollstat.waits Waits, v$rollstat.writes Writes,

sys.dba_rollback_segs.status status from v$rollstat, sys.dba_rollback_segs,

v$rollname where v$rollname.name(+) = sys.dba_rollback_segs.segment_name and

v$rollstat.usn (+) = v$rollname.usn order by rownum

 

 

15。耗资源的进程(top session

select s.schemaname schema_name, decode(sign(48 - command), 1,

to_char(command), 'Action Code #' || to_char(command) ) action, status

session_status, s.osuser os_user_name, s.sid, p.spid , s.serial# serial_num,

nvl(s.username, '[Oracle process]') user_name, s.terminal terminal,

s.program program, st.value criteria_value from v$sesstat st, v$session s , v$process p

where st.sid = s.sid and st.statistic# = to_number('38') and ('ALL' = 'ALL'

or s.status = 'ALL') and p.addr = s.paddr order by st.value desc, p.spid asc, s.username asc, s.osuser asc

 

 

16。查看锁(lock)情况

select /*+ RULE */ ls.osuser os_user_name, ls.username user_name,

decode(ls.type, 'RW', 'Row wait enqueue lock', 'TM', 'DML enqueue lock', 'TX',

'Transaction enqueue lock', 'UL', 'User supplied lock') lock_type,

o.object_name object, decode(ls.lmode, 1, null, 2, 'Row Share', 3,

'Row Exclusive', 4, 'Share', 5, 'Share Row Exclusive', 6, 'Exclusive', null)

lock_mode, o.owner, ls.sid, ls.serial# serial_num, ls.id1, ls.id2

from sys.dba_objects o, ( select s.osuser, s.username, l.type,

l.lmode, s.sid, s.serial#, l.id1, l.id2 from v$session s,

v$lock l where s.sid = l.sid ) ls where o.object_id = ls.id1 and o.owner

<> 'SYS' order by o.owner, o.object_name

 

 

17。查看等待(wait)情况

SELECT v$waitstat.class, v$waitstat.count count, SUM(v$sysstat.value) sum_value

FROM v$waitstat, v$sysstat WHERE v$sysstat.name IN ('db block gets',

'consistent gets') group by v$waitstat.class, v$waitstat.count

 

 

18。查看sga情况

SELECT NAME, BYTES FROM SYS.V_$SGASTAT ORDER BY NAME ASC

 

 

19。查看catched object

SELECT owner, name, db_link, namespace,

type, sharable_mem, loads, executions,

locks, pins, kept FROM v$db_object_cache

 

 

20。查看V$SQLAREA

SELECT SQL_TEXT, SHARABLE_MEM, PERSISTENT_MEM, RUNTIME_MEM, SORTS,

VERSION_COUNT, LOADED_VERSIONS, OPEN_VERSIONS, USERS_OPENING, EXECUTIONS,

USERS_EXECUTING, LOADS, FIRST_LOAD_TIME, INVALIDATIONS, PARSE_CALLS, DISK_READS,

BUFFER_GETS, ROWS_PROCESSED FROM V$SQLAREA

 

21。查看object分类数量

select decode (o.type#,1,'INDEX' , 2,'TABLE' , 3 , 'CLUSTER' , 4, 'VIEW' , 5 ,

'SYNONYM' , 6 , 'SEQUENCE' , 'OTHER' ) object_type , count(*) quantity from

sys.obj$ o where o.type# > 1 group by decode (o.type#,1,'INDEX' , 2,'TABLE' , 3

, 'CLUSTER' , 4, 'VIEW' , 5 , 'SYNONYM' , 6 , 'SEQUENCE' , 'OTHER' ) union select

'COLUMN' , count(*) from sys.col$ union select 'DB LINK' , count(*) from

 

22。按用户查看object种类

select u.name schema, sum(decode(o.type#, 1, 1, NULL)) indexes,

sum(decode(o.type#, 2, 1, NULL)) tables, sum(decode(o.type#, 3, 1, NULL))

clusters, sum(decode(o.type#, 4, 1, NULL)) views, sum(decode(o.type#, 5, 1,

NULL)) synonyms, sum(decode(o.type#, 6, 1, NULL)) sequences,

sum(decode(o.type#, 1, NULL, 2, NULL, 3, NULL, 4, NULL, 5, NULL, 6, NULL, 1))

others from sys.obj$ o, sys.user$ u where o.type# >= 1 and u.user# =

o.owner# and u.name <> 'PUBLIC' group by u.name order by

sys.link$ union select 'CONSTRAINT' , count(*) from sys.con$

 

23。有关connection的相关信息

1)查看有哪些用户连接

   select s.osuser os_user_name, decode(sign(48 - command), 1, to_char(command),

'Action Code #' || to_char(command) ) action, p.program oracle_process,

status session_status, s.terminal terminal, s.program program,

s.username user_name, s.fixed_table_sequence activity_meter, '' query,

0 memory, 0 max_memory, 0 cpu_usage, s.sid, s.serial# serial_num

from v$session s, v$process p where s.paddr=p.addr and s.type = 'USER'

order by s.username, s.osuser

 2)根据v.sid查看对应连接的资源占用等情况

select n.name,

v.value,

n.class,

n.statistic#

from v$statname n,

v$sesstat v

where v.sid = 71 and

v.statistic# = n.statistic#

order by n.class, n.statistic#

 3)根据sid查看对应连接正在运行的sql

select /*+ PUSH_SUBQ */

command_type,

sql_text,

sharable_mem,

persistent_mem,

runtime_mem,

sorts,

version_count,

loaded_versions,

open_versions,

users_opening,

executions,

users_executing,

loads,

first_load_time,

invalidations,

parse_calls,

disk_reads,

buffer_gets,

rows_processed,

sysdate start_time,

sysdate finish_time,

'>' || address sql_address,

'N' status

from v$sqlarea

where address = (select sql_address from v$session where sid = 71)

 

 

24.查询表空间使用情况select a.tablespace_name "表空间名称",

100-round((nvl(b.bytes_free,0)/a.bytes_alloc)*100,2) "占用率(%)",

round(a.bytes_alloc/1024/1024,2) "容量(M)",

round(nvl(b.bytes_free,0)/1024/1024,2) "空闲(M)",

round((a.bytes_alloc-nvl(b.bytes_free,0))/1024/1024,2) "使用(M)",

Largest "最大扩展段(M)",

to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') "采样时间"

from (select f.tablespace_name,

sum(f.bytes) bytes_alloc,

sum(decode(f.autoextensible,'YES',f.maxbytes,'NO',f.bytes)) maxbytes

from dba_data_files f

group by tablespace_name) a,

(select f.tablespace_name,

sum(f.bytes) bytes_free

from dba_free_space f

group by tablespace_name) b,

(select round(max(ff.length)*16/1024,2) Largest,

ts.name tablespace_name

from sys.fet$ ff, sys.file$ tf,sys.ts$ ts

where ts.ts#=ff.ts# and ff.file#=tf.relfile# and ts.ts#=tf.ts#

group by ts.name, tf.blocks) c

where a.tablespace_name = b.tablespace_name and a.tablespace_name = c.tablespace_name

 

25. 查询表空间的碎片程度

select tablespace_name,count(tablespace_name) from dba_free_space group by tablespace_name

having count(tablespace_name)>10;

alter tablespace name coalesce;

alter table name deallocate unused;

create or replace view ts_blocks_v as

select tablespace_name,block_id,bytes,blocks,'free space' segment_name from dba_free_space

union all

select tablespace_name,block_id,bytes,blocks,segment_name from dba_extents;

select * from ts_blocks_v;

select tablespace_name,sum(bytes),max(bytes),count(block_id) from dba_free_space

group by tablespace_name;

 

26.查看有哪些实例在运行:

select * from v$active_instances;

12:15 PM | Add a comment | Permalink | Blog it | Oracle

ORACLE性能调优原则

数据库的硬件配置:CPU、内存、网络条件

1.         CPU:在任何机器中CPU的数据处理能力往往是衡量计算机性能的一个标志,并且ORACLE是一个提供并行能力的数据库系统,在CPU方面的要求就更高了,如果运行队列数目超过了CPU处理的数目,性能就会下降,我们要解决的问题就是要适当增加CPU的数量了,当然我们还可以将需要许多资源的进程KILL掉;

2.         内存:衡量机器性能的另外一个指标就是内存的多少了,在ORACLE中内存和我们在建数据库中的交换区进行数据的交换,读数据时,磁盘I/O必须等待物理I/O操作完成,在出现ORACLE的内存瓶颈时,我们第一个要考虑的是增加内存,由于I/O的响应时间是影响ORACLE性能的主要参数,我将在这方面进行详细的讲解

3.         网络条件:NET*SQL负责数据在网络上的来往,大量的SQL会令网络速度变慢。比如10M的网卡和100的网卡就对NET*SQL有非常明显的影响,还有交换机、集线器等等网络设备的性能对网络的影响很明显,建议在任何网络中不要试图用3个集线器来将网段互联。

?         OS参数的设置

下表给出了OS的参数设置及说明,DBA可以根据实际需要对这些参数进行设置

内核参数名

说明

bufpages

对buffer空间不按静态分配,采用动态分配,使bufpages值随nbuf一起对buffer空间进行动态分配。

create_fastlinks

对HFS文件系统允许快速符号链接,

dbc_max_pct

加大最大动态buffer空间所占物理内存的百分比,以满足应用系统的读写命中率的需要。

dbc_min_pct

设置最小动态buffer空间所占物理内存的百分比

desfree

提高开始交换操作的最低空闲内存下限,保障系统的稳定性,防止出现不可预见的系统崩溃(Crash)。

fs_async

允许进行磁盘异步操作,提高CPU和磁盘的利用率

lotsfree

提高系统解除换页操作的空闲内存的上限值,保证应用程序有足够的可用内存空间。

maxdsiz

针对系统数据量大的特点,加大最大数据段的大小,保证应用的需要。(32位)

maxdsiz_64bit

maximum process data segment size for 64_bit

Maxssiz

加大最大堆栈段的大小。(32_bit

maxssiz_64bit

加大最大堆栈段的大小(64_bit

Maxtsiz

提高最大代码段大小,满足应用要求

maxtsiz_64bit

原值过大,应调小

Minfree

提高停止交换操作的自由内存的上限

Shmem

允许进行内存共享,以提高内存的利用率。

Shmmax

设置最大共享内存段的大小,完全满足目前的需要。

Timeslice

由于系统的瓶颈主要反映在磁盘I/O上,因此 降低时间片的大小,一方面可避免因磁盘I/O不畅造成CPU的等待,从而提高了CPU的综合利用率。另一方面减少了进程的阻塞量。

unlockable_mem

提高了不可锁内存的大小,使可用于换页和交换的内存空间扩大,用以满足系统对内存管理的要求。

 

摘自:http://www.zdnet.com.cn/developer/database/story/0,3800066906,39276980,00.htm

11:27 AM | Add a comment | Permalink | Blog it | Oracle

UNIX内存占用基本检查

 

1: 使用top指令.

  top指令是按cpu占用率排序的,如果想一次获得所有进程的快照,使用命令

top -n [最大进程数] -f 输出到文件,比如top -n 1000 -f topsnapshot.log

  top指令输出内存的统计信息包括

Memory: 2614368K (2249100K) real, 5838616K (5264696K) virtual, 113028K free  Page# 1/1

其中没有括号起来的是总数,括号括起来的部分是活动进程使用的内存数,free则是真实空闲的物理内存数.

进程信息的列包括

CPU TTY  PID USERNAME PRI NI   SIZE    RES STATE    TIME %WCPU  %CPU COMMAND

和内存相关的只有SIZERES

SIZE:任务的代码加上数据再加上栈空间的大小。 

RES:任务使用的物理内存的总数量

要检查进程是否有内存泄露,和实际占用的内存大小,RES列即可.

2:检查共享内存占用的内存容量

使用ipcs -m -b命令,-m表示检查共享内存,-b表示输出每个内存的字节数,得到的共享内存信息输出列包括:

T         ID     KEY        MODE        OWNER     GROUP      SEGSZ

SEGSZ列则是字节数.把每列相加则是共享内存占用的内存总数.

3: 调整内核动态高速缓冲区参数

HP-UX某些型号的服务器运行的时候需要几乎1G的内存维持系统运行,比如作为设备缓冲什么的.

可以用kmtune命令检查内核配置参数,动态高速缓冲区参数dbc_min_pct 和 dbc_max_pct参数表示一个高速缓冲区允许的可用内存的最小和最大百分比,dbc_max_pct的缺省值是50,一般设置为10即可.

4:HP-UX上还可以使用glance

glance是个很强的工具,可惜不是免费的....

11:16 AM | Add a comment | Permalink | Blog it | HPUX

July 27

Oracle的优化器(Optimizer)

本文的目的: 

1、说一说OracleOptimizer及其相关的一些知识。 

2、回答一下为什么有时一个表的某个字段明明有索引,当观察一些SQL的执行计划时,发现确不走索引的问题。 

3、如果你对 FIRST_ROWS、 ALL_ROWS这两种模式有疑惑时也可以看一下这篇文章。

开始吧:

 

Oracle在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行。分析语句的执行计划的工作是由优化器(Optimizer)来完成的。不同的情况,一条SQL可能有多种执行计划,但在某一时点,一定只有一种执行计划是最优的,花费时间是最少的。相信你一定会用Pl/sql DeveloperToad等工具去看一个语句的执行计划,不过你可能对RuleChooseFirst rowsAll rows这几项有疑问,因为我当初也是这样的,那时我也疑惑为什么选了以上的不同的项,执行计划就变了?

1、优化器的优化方式

Oracle的优化器共有两种的优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO)。 

ARBO方式:优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。比如我们常见的,当一个where子句中的一列有索引时去走索引。 

BCBO方式:依词义可知,它是看语句的代价(Cost),这里的代价主要指Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给出表的大小 、有少行、每行的长度等信息。这些统计信息起初在库内是没有的,是你在做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些我们应及时更新这些信息。在Oracle8及以后的版本,Oracle列推荐用CBO的方式。

我们要明了,不一定走索引就是优的 ,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时对这个表做全表扫描(full table scan)是最好的。

2、优化器的优化模式(Optermizer Mode)

优化模式包括Rule,Choose,First rows,All rows这四种方式,也就是我们以上所提及的。如下我解释一下:

Rule:不用多说,即走基于规则的方式。

Choolse:这是我们应观注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,RBO的方式。

First Rows:它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间。

All Rows:也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。

3、如何设定选用哪种优化模式

aInstance级别

我们可以通过在init.ora文件中设定OPTIMIZER_MODE=RULEOPTIMIZER_MODE=CHOOSEOPTIMIZER_MODE=FIRST_ROWSOPTIMIZER_MODE=ALL_ROWS去选用3所提的四种方式,如果你没设定OPTIMIZER_MODE参数则默认用的是Choose这种方式。

BSessions级别

通过SQL> ALTER SESSION SET OPTIMIZER_MODE=;来设定。

C、语句级别

这些需要用到Hint,比如

SQL> SELECT /*+ RULE */ a.userid, 

2 b.name, 

3 b.depart_name 

4 FROM tf_f_yhda a, 

5 tf_f_depart b 

6 WHERE a.userid=b.userid;

4、为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢 ?

A、不走索引大体有以下几个原因 

你在Instance级别所用的是all_rows的方式 

你的表的统计信息(最可能的原因

你的表很小,上文提到过的,Oracle的优化器认为不值得走索引。 

B、解决方法 

可以修改init.ora中的OPTIMIZER_MODE这个参数,把它改为RuleChoose,重起数据库。也可以使用4中所提的Hint. 

删除统计信息 

SQL>analyze table table_name delete statistics; 

表小不走索引是对的,不用调的。

5、其它相关

A、如何看一个表或索引是否是统计信息

SQL>SELECT * FROM user_tables 

2 WHERE table_name= 

3 AND num_rows is not null;

SQL>SELECT * FROM user_indexes 

2 WHERE table_name= 

3 AND num_rows is not null;

b、如果我们先用CBO的方式,我们应及时去更新表和索引的统计信息,以免生形不切合实的执行计划。

SQL> ANALYZE TABLE table_name COMPUTE STATISTICS; 

SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS;

具体的ANALYZE语句请参照Oracle8i/9i refrence文档。

12:42 PM | Add a comment | Permalink | Blog it | Oracle

oracle大数据量的导入和导出

在oracle中批量数据的导出是借助sqlplusspool来实现的。批量数据的导入是通过sqlload来实现的。

大量数据的导出部分如下:

/***************************

* sql脚本部分 demo.sql begin

**************************/

/**************************

* @author meconsea

* @date 20050413

* @msn meconsea@hotmail.com

* @Email meconsea@163.com

**************************/

//##--markup htmlhtml格式输出,缺省为off

//##--autocommit:自动提交insertupdatedelete带来的记录改变,缺省为off

//##--define:识别命令中的变量前缀符,缺省为on,也就是'&',碰到变量前缀符,后面的字符串作为变量处理.

set colsep''; //##--域输出分隔符

set echo off; //##--显示start启动的脚本中的每个sql命令,缺省为on

set feedback off; //##--回显本次sql命令处理的记录条数,缺省为on 

set heading off; //##--输出域标题,缺省为on

set pagesize 0; //##--输出每页行数,缺省为24,为了避免分页,可设定为0

set linesize 80; //##--输出一行字符个数,缺省为80

set numwidth 12; //##--输出number类型域长度,缺省为10

set termout off; //##--显示脚本中的命令的执行结果,缺省为on

set timing off; //##--显示每条sql命令的耗时,缺省为off

set trimout on; //##--去除标准输出每行的拖尾空格,缺省为off

set trimspool on; //##--去除重定向(spool)输出每行的拖尾空格,缺省为off

spool C:datadmczry.txt; 

select trim(czry_dm),trim(swjg_dm),trim(czry_mc) from dm_czry;

spool off;

EOF

/***********************

* demo.sql end

***********************/

在数据导入的时候采用sqlload来调用,在该部分调用的时候用java来调用sqlload

sqlload包括ctl控制文件。例如:

/*********************

* meconsea ctl

********************/

load data

infile 'C:datadmczry.txt'

replace into table DM_CZRY

fields terminated by X'09'

(CZRY_DM,SWJG_DM,CZRY_MC)

/********************

* end

注释:里面的replace可以改为append

*******************/

java程序如下:

在java程序用可以根据需求写成一个bat文件。 把数据库的配置和文件的路径写到一个properties

文件。

/*************************

* ide properties

************************/

Dserver=test/test@SJJZ

sqlldr=D:\oracle\ora92\bin\SQLLDR.EXE

ctldmczry=C:\data\ctl\dmczry.ctl

txtdmczry=C:\data\dmczry.txt

写个PropertyBean.java来操作properties文件。(偷懒不写了!)

用DmCzry.java来把记录导入db中。部分代码如下:

/****************************

代码摘要

*

***************************/

..............

sqlldr = pb.getSqlldr();

txt = pb.getTxtdmczry();

ctl = pb.getCtldmczry();

Dserver= pb.getDserver();

 

Process processCmd = Runtime.getRuntime().exec(sqlldr+" "+cmdStr);

.............

12:42 PM | Add a comment | Permalink | Blog it | Oracle

在Oracle中查看各个表、表空间占用空间的大小

查看当前用户每个表占用空间的大小:

Select Segment_Name,Sum(bytes)/1024/1024 From User_Extents Group By Segment_Name

查看每个表空间占用空间的大小:

Select Tablespace_Name,Sum(bytes)/1024/1024 From Dba_Segments Group By Tablespace_Name

12:36 PM | Add a comment | Permalink | Blog it | Oracle

July 22

Oracle 数据类型

Oracle 数据类型

 

数据类型

描述

VARCHAR2(size)

 

 

 

NVARCHAR2(size)

可变长度的字符串,其最大长度为 size 个字节。size 的最大值是 4000,而最小值是 1。您必须指定一个 VARCHAR2 的 size

 

可变长度的字符串,依据所选的国家字符集,其最大长度为 size 个字符或字节。size 的最大值取决于存储每个字符所需要的字节数,其上限为 4000 个字节。您必须为 NVARCHAR2 指定一个 size

NUMBER(p,s)

精度为 p 并且数值范围为 的数值。精度 的范围是从 到 38。数值范围 的范围是从 -84 到 127

LONG

可变长度的字符数据,其最大长度可达 2G 或 231 –1 个字节。

DATE

有效日期范围从公元前 4712 年 月 日到公元后 4712 年 12 月 31 日。

RAW(size)

长度为 size 字节的原始二进制数据。size 的最大值为 2000 字节。您必须为 RAW 值指定一个 size

LONG RAW

可变长度的原始二进制数据,其最大长度可达 2G 字节。

CHAR(size)

 

 

NCHAR(size)

 

固定长度的字符数据,其长度为 size 字节。size 的最大值为 2000 字节。默认或最小的 size 是一个字节。

 

固定长度的字符数据,其长度依据国家字符集的选择为 size 个字符或字节。size 的最大值取决于存储每个字符所需要的字节数,其上限为 2000 个字节。默认或最小的 size 是一个字符或字节,这取决于字符集。

CLOB

 

 

 

NCLOB

 

 

一个字符大型对象,可容纳单字节的字符。不支持宽度不等的字符集。最大大小为 4G 字节。

 

一个字符大型对象,可容纳固定宽度的多字节字符。不支持宽度不等的字符集。最大大小为 4G 字节。储存国家字符集数据。

BLOB

一个二进制大对象。最大大小为 4G 字节。

BFILE

包含一个大型二进制文件的定位器,其存储在数据库的外面。使得可以以字节流 I/O 访问存在数据库服务器上的外部 LOB。最大大小为 4G 字节。

 

 

 

 

 

3:57 PM | Add a comment | Permalink | Blog it | Oracle

July 19

ORACLE锁的管理

 ORACLE里锁有以下几种模式:

0none

1null      空 

2Row-S     行共享(RS):共享表锁  

3Row-X     行专用(RX):用于行的修改

4Share     共享锁(S):阻止其他DML操作

5S/Row-X   共享行专用(SRX):阻止其他事务操作

6exclusive 专用(X):独立访问使用

数字越大锁级别越高, 影响的操作越多。

一般的查询语句如select ... from ... ;是小于2的锁有时会在v$locked_object出现。

select ... from ... for update;      2的锁。

当对话使用for update子串打开一个游标时,

所有返回集中的数据行都将处于行级(Row-X)独占式锁定,

其他对象只能查询这些数据行,不能进行updatedeleteselect...for update操作。

insert / update / delete ... ;      3的锁。 

没有commit之前插入同样的一条记录会没有反应

因为后一个3的锁会一直等待上一个3的锁我们必须释放掉上一个才能继续工作。

创建索引的时候也会产生3,4级别的锁。

locked_mode2,3,4不影响DML(insert,delete,update,select)操作

但DDL(alter,drop)操作会提示ora-00054错误。

有主外键约束时 update / delete ... ; 可能会产生4,5的锁。

DDL语句时是6的锁。

以DBA角色查看当前数据库里锁的情况可以用如下SQL语句:

select object_id,session_id,locked_mode from v$locked_object;

select t2.username,t2.sid,t2.serial#,t2.logon_time 

from v$locked_object t1,v$session t2 

where t1.session_id=t2.sid order by t2.logon_time;

如果有长期出现的一列,可能是没有释放的锁。

我们可以用下面SQL语句杀掉长期没有释放非正常的锁:

alter system kill session 'sid,serial#';

如果出现了锁的问题, 某个DML操作可能等待很久没有反应。

当你采用的是直接连接数据库的方式,

也不要用OS系统命令 $kill process_num 或者 $kill -9 process_num来终止用户连接,

因为一个用户进程可能产生一个以上的锁, OS进程并不能彻底清除锁的问题。

记得在数据库级别用alter system kill session 'sid,serial#';杀掉不正常的锁。

5:42 PM | Add a comment | Permalink | Blog it | Oracle

July 18

利用STATSPAGK调整ORACLE性能

一、摘要

  大部分DBA都利用数据缓冲区命中率,latch free wait time等指标来做数据库性能调整。ORACLE提供的几个简单工具如STATSPACK(或以前版本的BSTAT/ESTAT)中包含了DBA 所需要的主要指标。但如何有效地利用这些数据调整性能?从那里开始调整?本文使用YAPP性能优化方法,结合STATSPACK提供的数据,给出了应该采取的调整步骤。

二、YAPP性能优化方法

  YAPP提供了另一种数据库性能调整方法,它不使用命中率等指标来衡量数据库的性能而是通过响应时间来衡量:

  Response time = service time + wait time

  即用户面对的响应时间由服务时间和等待时间组成。服务时间是处理你的请求实际使用的CPU时间,等待时间即等待资源可用所花费的时间。例如如果执行一个需要查找索引的SQL语句,CPU时间可能包括buffer cache中的索引数据块的处理时间,扫描该数据块找到所需行的时间等,此过程中ORACLE可能需要从盘上读数据,此时可能出现磁盘等待。

  YAPP方法的主要思路是找出service timewait time的主要组成部分,然后进行排序并根据顺序调整。因此在IO不是引起问题的原因时,你不会做出象数据缓冲区命中率太低,最好增加缓冲的结论’,SQL语句的CPU处理时间为20分钟时,你也不会做出必须将latchwait time减少20的调整决定。另外用YAPP做优化时,你可以通过减少整个时间(如用更快的磁盘)或单位时间(如减少访问磁盘次数)。因此我们称YAPP为基于时间的调优方法,基本步骤如下:

  (1)、得到服务时间和等待时间及其组成部分 

  (2)、将所有组成部分排序 

  (3)、依次优化每个部分 

  (4)、对表中的每一项,减少每次执行的代价或执行次数

  STATSPACKbstat/estat中的数据完全能满足基于时间而不是基于命中率的优化方法。然而实际上要找出所有耗时的部分有些困难,在分析细节时servicewait本身并不精确,例如当你等待磁盘IO时,实际是从OS的缓冲中读写,实际上它是service (即CPU)时间,因此响应时间更好的表达为:

  Response time = time compnent1+….+time componentn

  用户感知的响应时间由一系列时间成分组成,所谓性能优化就是优化最耗时的成分,依次类推。从ORACLE instance的角度,请求一般含三个部分:client (如SQLPLUSTUXEDO),前台进程(如LOCAL = NO的服务进程),后台进程(如DBWR)。

三、ORACLE中的时间记录

  所有的ORACLE进程(前台和后台)都会将所使用的CPU时间(service time)和各种等待事件所费时间记录下来,这些信息记录在SGA,用户可通过V$▁视图访问这些数据。这种数据分为session级和system级,用户可访问V$SYSTEM▁EVENTV$SYSSTAT等视图来获取这些信息。ORACLESTATSPACK工具(老版本中的BSTAT/ESTAT)就是查询这些视图来收集,计算和生成性能数据。要在ORACLE中产生时间记录,DBA必须在INIT.ORA中将TIMED▁STATISTICS设置为TRUE或通过ALTERSYSTEM将其定义为TRUE8i以前的版本中时间单位为1/100秒。9i以后时间单位为1/1,000,000(微秒)。本文主要面向system级的数据,但使用的方法适用于session级的数据。

  在基于时间的优化方法中,最重要的视图是V$SYSTEM▁EVENTV$SYSSTATV$LATCHV$SQLAREAV$SYSSTAT记录使用的CPU时间,V$SYSTEM▁EVENT记录进程等待时间花费的间,V$SQLAREA能用于找出最耗资源的SQL语句,而V$LATCH则可用于各种LATCH的等待信息。这些视图的详细结构和含义见Sewer Reference Mannual

四、利用STATSPACK优化性能

  前一节所说的V$▁ 中记录的数据都是系统启动后的累加值,从某一个时间点看这些累加值没有实际意义。只有每隔一段时间对这些累加值取样,计算出抽样之间的差别对优化才有价值。ORACLESTATSPACK就是完成定期取样的工作,一般可用ORACLEJOB来自动完成定期取样。数据收集完成后,DBA可以运行STATSPACK带的SPREPORT生成某两个取样点之间的差别。STATSPACK生成的报告中含有各种数据,包括上述四个视图中的数据。

  1、从STATSPACK报告中找出晌应时间组成部分

  基于时间的优化方法YAPP就是要找出最值得优化(最耗时)的成分。我们需找出前台进程使用的sevice time及等待事件花费的时间,service time信息可以从V$SYSSTAT中得到而事件等待花费的时间可从V$SYSTEM▁EVENT中得到。在STATSPACK报告中它们分别在 '''' Instance Activity Stats for DB '''' 和 '''' Wait Eventsfor DB '''' 一节中。尤其要注意三个时间成分:

  CPU used by this session Total CPU time spent. 

  Recursive cpu usage 

  Time spent doing recursive work in the foreground .   

  This includes data dictionary lookup and any PL /SQL work, including time spent 

by SQL inside 

  PL/SQL parse time cpu 

  CPU time spent parsing SQL statements

  Recursive cpu usageparse time cpu CPUCPU used by this session的组成部分,除此之外的CPU时间我们一律定义为other CPU

  下一步需找出wait time的组成部分,最简单的方法就是找出 '''' Top5Wait Events '''' 下的5个等待事件,另一种方法即在 '''' Wait events for DB '''' 一节中找出最主要的事件。

  下面是根据STATSPACK报告的数据,用基于YAPP方法的优化步骤:

  (1)、找出parse time cpu所花费的时间 

  (2)、找出CPU used by this session的值,减去parse time cpu,得出other CPU 

  (3)、找出最耗时的等待事件 

  (4)、将1—3的成分倒序排序,从第一项开始优化 

  (5)、如果最耗时的等待事件不是latch free,见Tuning possibilities for wait events 

  (6)、如果最耗时的等待事件是latch free,见Tuning possibilities for  latches 

  (7)、如果最耗时的成分是与CPU有关的成分,Tuning possibilities for CPU

  2Tuning possibilities for CPU

  recursive cpu usage  如果处理大量的PLSQL此成分可能很高,本文不深入讨论此问题产生的原因,但你需要找出你所有的PLSQL,包括存储过程。找出CPU开销最大的PLSQL过程并对其优化。如果PLSQL中的主要工作是完成过程处理而非执行SQL,高开销的recursive cpu usage可能是需要优化的成分。

  parse time cpu  分析(parsingSQL是一个开销很大的,它可以通过SQL语句的重用来避免。在预编译程序中,可通过增加MAXOPENCURSORS参数减少这部分开销。V$SQLPARSE▁CALLSEXECUTIONS可用来找出经常parse的语句。

  Other cpu  其它CPU主要用于处理缓冲区中的缓冲。一般而言,SQL语句花费的CPU时间与访问的缓冲区个数成比例,因此可以从V$SQL中的buffer gets得到SQL所防问的缓冲区个数,在STATSPACK中,可以查看 '''' SQL ordered by Gets for DB ''''。应对清单中的SQL语句优化。在bstat /estat报告中没有SQL语句,需定期查询V$SQLAREA,找出buffer gets增加最快的语句。9iV$SQL中含有CPU▁T|ME字段,记录语句所花费的时间。

  3Tuning possibilities for wait events

  db file scattered read  ORACLE全表扫描时,一次需读多个数据块,此时使用这一等待事件。i n i t .o r a中的db▁ file▁mutiblock▁read▁count定义了多数据块读取时,一次能读取的最大块数。一般此参数定义为4—16,与数据库大小无关。但值越大DB▁BLOCK▁SlZE应越小。如果db file scattered read所占比例较大,必须减少IO的代价(如使用更快的磁盘,均衡IO分布),或减少全表扫描的次数(优化SQL语句)。参见下面IO优化。

  db file sequential read  表示ORACLE顺序读数据块,一般出现在读索引。如果db file sequential read等待很长,必须减少IO的代价(如使用更快的磁盘,均衡IO分布),或增加缓冲区。参见下面IO优化。

  buffer busy waits  多个进程访问(修改)缓冲区中同一数据块时出现此等待事件。当表没有free lists而对表并行插入时,或回滚段个数太少时,会出现此事件,V$WA|TSTAT及 

STATSPACK报告可辅助找出原因。

  latch free  见下节。

  Enqueue  一般为应用程序使用的锁,例如SEELECT ... FOR UPDATE。如果此部分占用的时间较大,需分析应用系统,尤其是长时间占有锁资源的代码。要分析每个锁的等待时间不太可能,虽然V$LOCK记录了每种所等待的次数。

  log file sync  任何时候一个事物提交时,它将通知LGWRLOG▁BUFFER写入日志文件,如果此部分占用时间较长,应减少COMMIT的次数,此外应使用性能更好的IO系统,另一个相关的事件是'''' log buffer parallel write '''' ,也与IO系统或CPU资源太少有关。

  free buffer wait   当一个SESSION需要空闲缓冲区但不能获取时,出现此等待事件。它将通知DBWR将脏的缓冲区写入数据文件。需要确定是否需要优化IO系统或者增加DBWR的个数,如果此事件不是由于IO系统性能引起的,可考虑增加缓冲区。

  rdbms ipc message  这些事件为空闲事件,一般应占主要的时间。''''

  pmon timer

  smon timer

  SQL*Net message 

  from client

  Tuning possibilities for latches

  shared pool   parsing,尤其是hard parsing时。如果应用程序使用常量而不是BIND变量,可能会对此latch大量竞争,8.1.6以后可在init.ora中设置cursor▁sharingforce来减少hard parsing和对此latch的竞争,应用程序应保证只分析一次,执行多次。

  library cache  soft parsinghard parsing时都会大量使用此latch,如有可能应修改应用程序,减少竞争。在init.ora中设置cursor▁sharingforce可减少soft parsinghard parsing需要的library cache。此外定义session▁cached▁cursors也能减少同一sessionsoft parsinglibrary cache的竞争。此外还可以定义cursor▁space▁for▁time=true

  mw cache  row cache保护字典信息,如表和列的信息。hard parsing需要row cache 。在init.ora中设置cursor▁sharingforce可减少竞争。

  cache buffer chain   保护缓冲区的hash chain,用于对缓冲区的每次访问。一般可通过减少访问缓冲区次数来减少对l|atch的竞争。利用X$BH可以找出某些hash chain是否有许多的缓冲区,经常会有热块(如root index block)可能引起竞争。

  cache buffer lru chain  数据缓冲一组LRU块组成的链。每一个由一个cache buffer lru  chain 保护通过增加db▁ block▁lru▁latches可减少竞争。

  4Tuning possibilities for I/O 

如果db file scattered/sequential read等直接的事件或file writeDBWR/LGWR)等非直接事件占用的时间比例较大,需要检查IO的效率。STATSPACK报告中有一节为 ''''Tablespace IO Summary for DB'''' 其中列出了表空间名称和它们的lO rate。另一节'''' file IO Statistics for DB''''列出了每个数据文件和它们的IO rate。首先应检查IO rate是否在期望的范围,其次应检查IO分布。如果IO rate 在可接受的范围(带cache的文件2—10ms或裸设备的每次IO 5—20ms)而且所有的数据文件IO  rate相似,那么可以肯定IO系统的性能符合要求。这种情况下减少每次IO代价没有必要,应该减少IO的次数(增加缓冲区或优化SQL)。然而如果IO rate大大超出合理范围或分布不合理,你需要重组IO子系统,如使用更多的磁盘驱动器,修改结构(如不使用RAID5),或IO重新分布。

五、值得注意的地方

  虽然ORACLE的统计和等待事件可以为你找出系统瓶颈提供了很好的数据,但有些情况这些数据可能会误导用户:

  ·ORACLE 8i以前的版本时间单位是1/100秒,但在某些特别|的系统中其精度不够。因而某些发生过的事件可能没有记录,而某些发生时间并不很长的事件记录的时间要比实际的时间长。这个问题在9i中不会出现(计量单位是1/1,000,000秒)。

  ·ORACLE前台进程花费的CPU时间记录比较粗糙,CPU used by this session远远大于实际使用配的时间,唯一能做的估计是所用CPU时间与所访问的缓冲区个数成比例,但在运行大的PLSQL,复杂的表达式,表连接时这种估计是不精确的。一般而言,这类估计在OLTP类型的应用系统是有效的,对DSS系统这种估计是不精确的。

  ·V$SYSSTAT视图包含前台和后台进程时间的总和,然而CPU时间成分中只有前台进程所用的时间值得注意,某些后台进程(尤其是DBWRLGWR)使用了大量的CPU,导致前台进程统计配的不精确。

  ·某些时间没有计算。如SQL*NET的时间,但它影响响应时间。

  ·YAPP中只考虑了ORACLE前台进程使用的时间,如果ORACLE所用的时间只占响应时间的很小部分,优化ORACLE不会带来任何性能改进。

六、IBSTAT/ESTAT的使用

  STATSPACK只有8.1.6以后的版本才有,如果使用的老的版本只有BSTAT/ESTAT,两者的主要区别是:

  ·BSTAT/ESATDBA直接手工运行而不通过ORACLE JOB自动运行,每运行一次只收集一个时间间隔的数据。

  ·BSTAT/ESAT没有SQL语句的信息,如果OTHER CPU是开销最大的成分,需要查询V$SQL找出最耗资源的SQL

  ·没有TOP5 WAIT EVENT,需查找视图找出最耗时的事件。

[关闭窗口]

1:41 PM | Add a comment | Permalink | Blog it | Oracle

Oracle性能调优实践中的几点心得

很多的时侯,做Oracle DBA的我们,当应用管理员向我们通告现在应用很慢、数据库很慢的时侯,我们到数据库时做几个示例的Select也发现同样的问题时,有些时侯我们会无从下手,因为我们认为数据库的各种命种率都是满足Oracle文档的建议。实际上如今的优化己经向优化等待(waits)转型了,实际中性能优化最根本的出现点也都集中在IO,这是影响性能最主要的方面,由系统中的等待去发现Oracle库中的不足、操作系统某些资源利用的不合理是一个比较好的办法,下面把我的一点实践经验与大家分享一下,本文测重于Unix环境。

一、通过操作系统的一些工具检查系统的状态,比如CPU、内存、交换、磁盘的利用率,根据经验或与系统正常时的状态相比对,有时系统表面上看起来看空闲这也可能不是一个正常的状态,因为cpu可能正等待IO的完成。除此之外我们还应观注那些占用系统资源(cpu、内存)的进程。

1、如何检查操作系统是否存在IO的问题?使用的工具有sar,这是一个比较通用的工具。

  Rp1#Sar -u 2 10

  即每隔2秒检察一次,共执行20次,当然这些都由你决定了。

  示例返回:

  HP-UX hpn2 B.11.00 U 9000/800    08/05/03

  18:26:32    %usr    %sys    %wio   %idle

  18:26:34      80       9      12       0

  18:26:36      78      11      11       0

  18:26:38      78       9      13       1

  18:26:40      81      10       9       1

  18:26:42      75      10      14       0

  18:26:44      76       8      15       0

  18:26:46      80       9      10       1

  18:26:48      78      11      11       0

  18:26:50      79      10      10       0

  18:26:52      81      10       9       0

  Average       79      10      11       0

    其中的%usr指的是用户进程使用的cpu资源的百分比,%sys指的是系统资源使用cpu资源的百分比,%wio指的是等待io完成的百分比,这是值得我们观注的一项,%idle即空闲的百分比。如果wio列的值很大,如在35%以上,说明你的系统的IO存在瓶颈,你的CPU花费了很大的时间去等待IO的完成。Idle很小说明系统CPU很忙。像我的这个示例,可以看到wio平均值为11说明io没什么特别的问题,而我的idle值为零,说明我的cpu已经满负荷运行了。

当你的系统存在IO的问题,可以从以下几个方面解决

  ♀联系相应的操作系统的技术支持对这方面进行优化,比如hp-ux在划定卷组时的条带化等方面。

  ♀查找Oracle中不合理的sql语句,对其进行优化

  ♀Oracle中访问量频繁的表除合理建索引外,再就是把这些表分表空间存放以免访问上产生热点,再有就是对表合理分区。

2、关注一下内存。

    常用的工具便是vmstat,对于hp-unix来说可以用glance,Aix来说可以用topas,当你发现vmstatpi列非零,memory中的free列的值很小,glance,topas中内存的利用率多于80%时,这时说明你的内存方面应该调节一下了,方法大体有以下几项。

  ♀划给Oracle使用的内存不要超过系统内存的1/2,一般保在系统内存的40%为益。

  ♀为系统增加内存

  ♀如果你的连接特别多,可以使用MTS的方式

  ♀打全补丁,防止内存漏洞。

3、如何找到点用系用资源特别大的Oraclesession及其执行的语句。

Hp-unix可以用glance,top

IBM AIX可以用topas

些外可以使用ps的命令。

通过这些程序我们可以找到点用系统资源特别大的这些进程的进程号,我们就可以通过以下的sql语句发现这个pid正在执行哪个sql,这个sql最好在pl/sql developer,toad等软件中执行<>中的spid换成你的spid就可以了。

SELECT a.username,

       a.machine,

       a.program,

       a.sid,

       a.serial#,

       a.status,

       c.piece,

       c.sql_text

  FROM v$session a,

       v$process b,

       v$sqltext c

 WHERE b.spid=  

   AND b.addr=a.paddr

   AND a.sql_address=c.address(+)

 ORDER BY c.piece    

   我们就可以把得到的这个sql分析一下,看一下它的执行计划是否走索引,对其优化避免全表扫描,以减少IO等待,从而加快语句的执行速度。

提示:我在做优化sql时,经常碰到使用in的语句,这时我们一定要用exists把它给换掉,因为Oracle在处理In时是按Or的方式做的,即使使用了索引也会很慢。

比如:

SELECT  col1,col2,col3 FROM table1 a 

 WHERE a.col1 not in (SELECT  col1 FROM table2)

       可以换成:

SELECT  col1,col2,col3 FROM table1 a 

 WHERE not exists

 (SELECT  'x'  FROM table2 b

WHERE  a.col1=b.col1)

4、另一个有用的脚本:查找前十条性能差的sql.

 SELECT * FROM 

  (

   SELECT PARSING_USER_ID

          EXECUTIONS,

          SORTS,

          COMMAND_TYPE,

          DISK_READS,

          sql_text

      FROM  v$sqlarea

     ORDER BY disk_reads DESC 

   )  

  WHERE ROWNUM<10 ;

 

二、迅速发现Oracle Server的性能问题的成因,我们可以求助于v$session_wait这个视图,看系统的这些session在等什么,使用了多少的IO。以下是我提供的参考脚本:

脚本说明:查看占io较大的正在运行的session

 SELECT se.sid,

       se.serial#,

       pr.SPID,

       se.username,

       se.status,

       se.terminal,

       se.program,

       se.MODULE,

       se.sql_address,

       st.event,

       st.p1text,

       si.physical_reads,

       si.block_changes 

  FROM v$session se,

       v$session_wait st,

       v$sess_io si,

       v$process pr

 WHERE st.sid=se.sid 

   AND st.sid=si.sid

   AND se.PADDR=pr.ADDR

   AND se.sid>6

   AND st.wait_time=0 

   AND st.event NOT LIKE '%SQL%'

 ORDER BY physical_reads DESC

对检索出的结果的几点说明:

1、我是按每个正在等待的session已经发生的物理读排的序,因为它与实际的IO相关。

2、你可以看一下这些等待的进程都在忙什么,语句是否合理?

  Select sql_address from v$session where sid=;

  Select * from v$sqltext where address=;

执行以上两个语句便可以得到这个session的语句。

你也以用alter system kill session 'sid,serial#';把这个session杀掉。

3、应观注一下event这列,这是我们调优的关键一列,下面对常出现的event做以简要的说明:

abuffer busy waitsfree buffer waits这两个参数所标识是dbwr是否够用的问题,与IO很大相关的,当v$session_wait中的free buffer wait的条目很小或没有的时侯,说明你的系统的dbwr进程决对够用,不用调整;free buffer wait的条目很多,你的系统感觉起来一定很慢,这时说明你的dbwr已经不够用了,它产生的wio已经成为你的数据库性能的瓶颈,这时的解决办法如下:

a.1增加写进程,同时要调整db_block_lru_latches参数

示例:修改或添加如下两个参数

  db_writer_processes=4

  db_block_lru_latches=8

a.2开异步IOIBM这方面简单得多,hp则麻烦一些,可以与Hp工程师联系。

bdb file sequential read,指的是顺序读,即全表扫描,这也是我们应该尽量减少的部分,解决方法就是使用索引、sql调优,同时可以增大db_file_multiblock_read_count这个参数。

cdb file scattered read,这个参数指的是通过索引来读取,同样可以通过增加db_file_multiblock_read_count这个参数来提高性能。

dlatch free,与栓相关的了,需要专门调节。

e、其他参数可以不特别观注。

 

 

SMON: Parallel transaction recovery tried 引发的问题

 

 SMON: Parallel transaction recovery tried 这个一般是在具有在跑大数据量的 transaction的时候kill掉了进程而导致 smon 去清理 回滚段时导致的。

这个在业务高峰期的时候,如果发现这个,有可能导致 SMON 占用了 100% cpu 而导致 系统 hang 在那边。

即使你shutdown immediate ,oracle 也会等待 smon 清理完毕才能关机,而这个等待过程也许是漫长的。

如果你 shutdown abort,那么oracle会马上shutdown ,但是,当你startup的时候,有可能就会很慢,因为 smon 会接着清理 undo,这个等待过程也许是很漫长的:

— — — —————————————————————————————————— 

Completed: ALTER DATABASE   MOUNT

Thu Aug 26 22:43:57 2010

ALTER DATABASE OPEN

Thu Aug 26 22:43:57 2010 

Beginning crash recovery of 1 threads

Thu Aug 26 22:43:57 2010 

Started first pass scan

Thu Aug 26 22:43:57 2010

Completed first pass scan

 402218 redo blocks read, 126103 data blocks need recovery

Thu Aug 26 22:45:05 2010

Restarting dead background process QMN0

QMN0 started with pid=16

Thu Aug 26 22:45:19 2010

Started recovery at

 Thread 1: logseq 13392, block 381202, scn 0.0

Recovery of Online Redo Log: Thread 1 Group 3 Seq 13392 Reading mem 0

  Mem# 0 errs 0: /zxindata/oracle/redolog/redo03.dbf

Recovery of Online Redo Log: Thread 1 Group 1 Seq 13393 Reading mem 0

  Mem# 0 errs 0: /zxindata/oracle/redolog/redo01.dbf

Thu Aug 26 22:45:21 2010

Completed redo application 

Thu Aug 26 22:48:35 2010

Ended recovery at

 Thread 1: logseq 13393, block 271434, scn 2623.1377219707

 126103 data blocks read, 115641 data blocks written, 402218 redo blocks read

Crash recovery completed successfully 

________________________________________________

看红色标注的那个,等待了 3 分钟才做完 recovery。

那如何才能让它快呢,metalink(238507.1 ) 有给出一些做法:

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

1. Find SMON's Oracle PID:

Example:

SQL> select pid, program from v$process where program like '%SMON%';

       PID PROGRAM

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

         6 oracle@stsun7 (SMON) 

2. Disable SMON transaction cleanup:

SVRMGR> oradebug setorapid 

SVRMGR> oradebug event 10513 trace name context forever, level 2 

3. Kill the PQ slaves that are doing parallel transaction recovery. 

You can check V$FAST_START_SERVERS to find these.

4. Turn off fast_start_parallel_rollback:

alter system set fast_start_parallel_rollback=false; 

If SMON is recovering, this command might hang, if it does just control-C out of it.  You may need to try this many times to get this to complete (between SMON cycles).

5. Re-enable SMON txn recovery:

SVRMGR> oradebug setorapid 

SVRMGR> oradebug event 10513 trace name context off 

——————————————————————————————————

以上的思路主要是要把 SMON 并行 recovery 的功能给改成非并行,主要

是 fast_start_parallel_rollback 这个参数的作用。

There are cases where parallel transaction recovery is not as fast as serial transaction recovery, because the pq slaves are interfering with each other. This depends mainly on the  type of changes that need to be made during rollback and usually may happen when rolling back INDEX Updates in parallel. 

 

参考至:http://hi.baidu.com/%CC%D8%B0%AE%C0%B6%C1%AB%BB%A8/blog/item/9af29302b820fab22eddd439.html

如有错误,欢迎指正

 

Kill session

 alter system kill session 'sid,serial#' ;

被kill掉的session,状态会被标记为killed,Oracle会在该用户下一次touch时清除该进程.

我们发现当一个session被kill掉以后,该session的paddr被修改,如果有多个session被kill,那么多个session

的paddr都被更改为相同的进程地址

SQL> select saddr,sid,serial#,paddr,username,status from v$session where username is not null;

SADDR           SID    SERIAL# PADDR    USERNAME                       STATUS

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

542E0E6C         11        314 542B70E8 EYGLE                          INACTIVE

542E5044         18        662 542B6D38 SYS                            ACTIVE

 

 

SQL> alter system kill session '11,314';

 

System altered.

 

增加表空间大小的四种方法

Meathod1:给表空间增加数据文件

ALTER TABLESPACE app_data ADD DATAFILE

'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF' SIZE 50M;

 

Meathod2:新增数据文件,并且允许数据文件自动增长

ALTER TABLESPACE app_data ADD DATAFILE

'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP04.DBF' SIZE 50M

AUTOEXTEND ON NEXT 5M MAXSIZE 100M;

 

Meathod3:允许已存在的数据文件自动增长

ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF'

AUTOEXTEND ON NEXT 5M MAXSIZE 100M;

 

Meathod4:手工改变已存在数据文件的大小

ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP02.DBF'

RESIZE 100M;

自动添加数据文件

set serveroutput on;

declare

Tablespacename Varchar(500);

  temp_file_name Varchar(500);

 file_name Varchar(500);

 free           Number(10,2);

 rate           Number(10,2);

 total           Number(10,2);

 used           Number(10,2);

 Vs_Sql         Varchar2(500);

 Data_File_No   Number(4);

 cursor cur_t  is

  select a.tablespace_name tablespace_name,a.total as total,a.total-a.free_space as used,(a.total-a.free_space)/a.total as rate, b.file_name file_name from (

  select f.tablespace_name tablespace_name,sum(f.bytes)/(1024*1024) as free_space,sum(d.bytes)/(1024*1024) as total

from dba_free_space f,dba_data_files  d

 where f.tablespace_name=d.tablespace_name and f.tablespace_name like '%GPS%' group by f.tablespace_name) a,(select max(file_name) file_name,tablespace_name from dba_data_files group by tablespace_name ) b where a.tablespace_name=b.tablespace_name;

 

 tablespace_info cur_t%rowtype;

 

Begin

  for tablespace_info in cur_t  loop

           rate:=tablespace_info.rate;

           total:=tablespace_info.total;

           used:=tablespace_info.used;

           Tablespacename:=tablespace_info.tablespace_name;

           file_name:=tablespace_info.file_name;

         

            If rate >=80 Then

            

               dbms_output.put_line(Tablespacename||' '||file_name||' '||rate);

            

            temp_file_name:=file_name;

            temp_file_name:=substr(file_name,0,INSTR (file_name, '.')-1);

            temp_file_name:=temp_file_name||'_'||to_char(sysdate,'yyyymmddhh24miss')||'.dbf';

             

        Vs_Sql := 'alter tablespace '||Tablespacename||' add datafile '''||temp_file_name||''' size 200M autoextend on next 100m maxsize UNLIMITED ';

         dbms_output.put_line(Vs_Sql);

        --alter中的路径需要根据本地数据库的安装路径修改 

        Execute Immediate Vs_Sql;

       End If;

  end loop;

End ;

 

修改索引表空间

  select 'alter index ' ||index_name|| ' rebuild tablespace FLTIDX;' index_name from  dba_indexes where owner like '%FLT%' and table_owner='FLT' and tablespace_name='FLT' and index_name  like '%PK%';

  

  select index_name,table_owner,tablespace_name from dba_indexes where owner like '%FLT%' and table_owner='FLT' and tablespace_name='FLTIDX' ;

  

   select index_name,table_owner,tablespace_name from dba_indexes where owner like '%FLT%' and table_owner='FLT' and tablespace_name='FLT' and index_name not like '%PK%';

  

  

  select * from  dba_indexes where owner like '%FLT%' and table_owner='FLT';

  alter index ANSWER_PK rebuild tablespace FLTIDX;

删除重复数据

delete from 表名 a 

  where a.rowid != 

  ( 

  select max(b.rowid) from 表名 b 

  where a.字段1 = b.字段1 and 

  a.字段2 = b.字段2 

)

 

 

 

查找sessionpsid

select a.sid, a.SERIAL#, b.spid, a.status, a.PROGRAM

from v$session a, V$PROCESS b

where a.sid in (29, 30, 32, 77, 120, 144, 151)

and a.paddr=b.ADDR

order by a.sid;

清除归档日志

rman target/ 

或rman target/@orcl 

在命令窗口里面执行 

DELETE ARCHIVELOG ALL COMPLETED BEFORE 'SYSDATE-7'; 

魏健康 09:41:17

ALTER DATABASE ARCHIVELOG;

魏健康 09:41:31

ALTER DATABASE NOARCHIVELOG;

魏健康 09:41:37

 ARCHIVE  LOG  LIST

 

RAC 启动和停止

[oracle@node1 ~]$ crs_stat 

[oracle@node1 ~]$ crs_start -all 

[oracle@node1 ~]$ crs_stop -all 

[oracle@node1 ~]$ crs_stop "ora.fyweb.db" 

[oracle@node1 ~]$ crs_start "ora.fyweb.db" 

删除表空间,表分区

alter table ALARM_REALTIME drop partition flt_data_part_201301;

drop tablespace test_data including contents and datafiles;

 

查询oracle进程现在执行的sql

 

SELECT   /*+ ORDERED */

         sql_text

    FROM v$sqltext a

   WHERE (a.hash_value, a.address) IN (

            SELECT DECODE (sql_hash_value,

                           0, prev_hash_value,

                           sql_hash_value

                          ),

                   DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)

              FROM v$session b

             WHERE b.paddr = (SELECT addr

                                FROM v$process c

                               WHERE c.spid = 5396))

ORDER BY piece ASC;

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值