oracle性能优化

Posted wangzihong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了oracle性能优化相关的知识,希望对你有一定的参考价值。

--oracle性能优化
--性能的定位
--原则 尽可能从小范围分析问题
sql层 :能定位到sql,就不要从会话层面分析 
工具 执行计划 1005310046 

会话层:从系统层面分析
v$session v$sesstat v$session_wait v$sql v$lock sql_trace 

系统层
AWR os tools 

高效的sql来自于对业务的理解和sql执行过程的理解
业务逻辑 - 优化器无能为力

create table mytable(
id number
,value varchar2(50)
)

select * from mytable for update;

set autotrace on --打开执行计划查看
set autotrace off--关闭执行计划查看
set autotrace on explain --只显示查询结果和执行计划 
set autotrace on statistics --只显示结果和统计信息
set autotrace traceonly --不显示查询输出,显示执行计划和统计信息 
set autot traceonly explain --只显示执行计划 
set autot traceonly statistics --只显示统计信息

--和前面一次的数做叠加
select 
     t1.id,t1.value,sum(t2.value)
from mytable t1
join mytable t2
  on t2.id <= t1.id 
group by t1.id,t1.value 

--查看sql的执行计划
explain plan for 
select 
     t1.id,t1.value,sum(t2.value)
from mytable t1
join mytable t2
  on t2.id <= t1.id 
group by t1.id,t1.value 

select * from table(dbms_xplan.display);

--使用分析函数改写sql
explain plan for 
select 
     id,value,sum(value) over(order by id)
from mytable;

select * from table(dbms_xplan.display);

sql语言本质上是集合的操作
-tablesan
-index range scan
-index fast scan
-nested loop join
-merge join 
-hash join 

=============
性能优化 lock 

么可以并发就没有锁

drop table t purge;
create table t(id int primary key);
--开两个窗口插入下面数据
insert into t values(1);
--在第一个窗口选择是否提交或回滚,观察第二个页面变化

oracle中锁的分类
enqueues 队列类型的锁,通常和业务相关的
latches 系统资源方面的锁,比如内存结构,sql解析 

锁的原则
1 只有被修改时,行才会被锁定
2 一条语句修改了一条记录,只有这条记录被锁定,oracle数据库不存在锁升级
3 当某行被修改时,它阻塞被人对它的修改
4 当一个事务修改一行时,将在这个行上加上行锁(tx),用于阻止其它事务对相同行的修改
5 读不会阻止写 例外select ...for update
6 写不会阻塞读
7 当一行被修改后,oracle通过回滚段提供给数据的一致性读

oracle中锁的类型
select type,name from v$lock_type;

tm表锁:发生在insertupdatedelete 目的是保证操作能够正常进行,阻止其它人对表执行ddl操作
tx锁 事务锁(行锁)对于正在修改的数据,阻止其它会话进行修改。

select sid,type,id1,id2,lmode,request,ctime,block from v$lock where type in (TM,TX) order by 1,2;
select object_name from dba_objects where object_id=13501;
select sid,event from v$session_wait where sid in (22,23);

select ... for update 锁定查询到的数据

tm锁的几种模式 lock mode 
模式 锁定的sql 排斥的模式 允许的sql
2 lock table t in row share mode; 6 select insert update delete for update
3 lock table t in row exclusive mode;4,5,6 select /insert/....
4 lock table t in share mode; 3,5,6 select 
5 lock table t in share row exclusive mode; 3,4,5,6 select 
6 lock table t in exclusive mode; 2,3,4,5,6 select 

为什么需要手工锁定表:

=================
05 基于引用关系的锁定 RI锁 

create table p(id int primary key);
create table c(id references p(id));

select sid,type,id1,id2,lmode,request,block
  from v$lock where type in (TM,TX) order by 1,2;
  
select object_name from dba_objects where object_id in (13504,13506);
插入数据时在从表上面加表级锁 

BI锁和外键索引

死锁:两个会话互相持有对方的资源
会话1:
create table t(id int primary key);
insert into t values(1);

会话2:
insert into t values(2);
insert into t values(1);  --此时出现阻塞等待

会话1:
insert into t values(2);

会话1出现阻塞等待,会话2报错
ORA-00060: 等待资源时检测到死锁

====================
06 latch门闩 
latch的目的
    保证资源的串行访问
        -保证sga的资源访问
        -保护内存的分配
    保证执行的串行化
        -保护关键资源的串行执行
        -防止内存结构损坏

latch --sga
资源的请求和分配
共享池
    -sql解析 sql重用
数据缓冲池
    -数据访问、数据写入磁盘、数据读入内存
    -修改数据块
    -数据段扩展
    
oracle有哪些latch 
select * from v$latchname;

latch的获取
wait方式--如果无法获取请求的latch 
    -spin 
     当一个会话无法获得需要的latch时,会继续使用cpu,达到一个间隔后,再次尝试,达到最大重试次数
    -sleep 
     当一个会话无法获得需要的latch时,会等待一段时间 
     
no wait方式-如果无法获取请求的latch 
    - 不会发生sleep或者spin
    - 转而去获取其它可用的latch
    
shared pool里的latch争用-绑定变量

declare 
  l_cnt number;
begin 
  for i in 1..10000 loop
    execute immediate select count(*) from t where x =||i into l_cnt;
  end loop;
end;
/

declare 
  l_cnt number;
begin 
  for i in 1..10000 loop
    select count(*) into l_cnt from t where x = i;
  end loop;
end;
  

buffer cache 数据区 
desc x$bh 数据块头
会话访问数据块
    step1 latch 
    step2 hash bucket 
    step3 数据块 
步骤:
1 hash the block address
2 get bucket latch 
3 look for header 
4 found read block in cache 
5 not found read block off disk  

data buffer中的latch争用 -热块
    表数据块争用
    热块索引数据热块
    文件头数据块-并发修改

latch相关的视图 - v$latch 
v$latch 
    每个latch的统计信息的一个汇总,每一条记录表示一种latch
    select name,gets,misses,sleeps from v$latch where name like cache%;
    misses:请求不成功次数
    sleeps:成功获取前sleeping次数
    immediate_gets:以immediate模式latch请求数
    immediate_misses:以immediate模式请求失败次数
    
v$latchholder 
    包含了当前latch持有者的信息
    通过视图中的pid和sid信息
    
v$latch_children 
    存储latch信息的视图
    
AWR报告中的latch部分

latch优化思路
 AWR报告
 通过动态视图v$latch 分析当前latch资源情况
 确定争用最大的latch 
 分析可能的原因
 应用层面和数据库层面考虑 
 
 =========
 08 优化器和执行计划
 执行计划
 sql语句访问和处理数据的方式 
 
 执行计划 数据的访问
    直接表的访问
        -并行
        -多数据块
    通过索引访问
        -index unique scan 索引唯一扫描 
        -index range scan 索引范围扫描
        -index full scan 索引全部扫描
        -index fast full scan 索引快速全部扫描
        -index skip scan 索引切块扫描
        
数据的处理
    order by group by 
数据的关联处理
    -nested loop join 嵌套循环连接 小表有索引
    -merge join 先排序
    -hash join 大表和小表关联
    
通过表访问数据
--索引唯一扫描
SQL> explain plan for
  2  select * from t where id=2;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2719494768
--------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |     1 |    26 |     2   (0)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |     1 |    26 |     2   (0)|
|*  2 |   INDEX UNIQUE SCAN         | SYS_C003776 |     1 |       |     1   (0)|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID"=2)
 
14 rows selected
--索引范围扫描 
SQL> explain plan for
  2  select * from t where id>5;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1744232805
--------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |     1 |    26 |     1   (0)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |     1 |    26 |     1   (0)|
|*  2 |   INDEX RANGE SCAN          | SYS_C003776 |     1 |       |     1   (0)|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID">5)
Note
-----
   - dynamic sampling used for this statement (level=2)
 
18 rows selected

--索引快速扫描
SQL> explain plan for
  2  select count(*) from t;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2375626531
-----------------------------------------------------------------------------
| Id  | Operation             | Name        | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT      |             |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE       |             |     1 |            |          |
|   2 |   INDEX FAST FULL SCAN| SYS_C003776 |     3 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
 
13 rows selected

--整个索引的扫描
SQL> explain plan for
  2  select id from t order by id;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3503263006
--------------------------------------------------------------------------------
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |             |     3 |    39 |     2   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | SYS_C003776 |     3 |    39 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
 
12 rows selected

--索引跳跃扫描


数据集的关联
--hash join 
--先把小表hash到内存中,然后过来关联
SQL> explain plan for
  2  select t.*,t2.* from t,t2 where t.id = t2.id;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 106979157
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     5 |   260 |     7  (15)| 00:00:01 |
|*  1 |  HASH JOIN         |      |     5 |   260 |     7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T    |     5 |   130 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| T2   |     5 |   130 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T"."ID"="T2"."ID")
Note
-----
   - dynamic sampling used for this statement (level=2)
 
19 rows selected

--nested loops 
--从其中的一张表拿数据到另外一张表中去匹配 

--sort merge join 

--并行
    
==================
09 oracle的优化器 
cbo 依据一套数据模型,计算数据访问和处理的成本,择最优成本为执行方案
CBO的工作模式
    all_rows 以结果集的全部处理完毕为目的
    first_rows(n) 以最快返回n行为目的 分页 
优化器模式的设置方式
    参数设置
        optimizer_mode 
    会话设置
        alter session set optimizer_mode=all_rows;
    sql设置
        select /*+ all_rows */ count(*) from t;
        
cost 代价
选择性 selectivity - user_tab_col_statistics 
索引的选择性 - user_indexes 
cardinality 集的市 
    在执行计划中每一步操作返回的记录数
    CBO通过这个值的权重计算,决定使用哪一种方式访问数据
    10g后 rows 评估出来的数
    
    
exec dbms_stats.gather_table_stats(user,t,method_opt=>for all columns size 1);
不做直方图 

索引 clustering factor 簇 集群因子 
集群因子 索引代价的评估
出现一次数据块的跳转 集群因子 +1 

CBO的核心 成本的计算
数据访问的成本的估算
    I/O成本的估算
        全表扫描
        索引(单数据块 多数据块)
    CPU成本的估算
数据处理的成本
    CPU成本的估算 
    
==============
10 hints 
oracle的hints 
hints是用来约束优化器行为的一种技术
    优化器模式 
        all_rows 
        first_rows 
    数据访问路径 
        基于表的数据访问
        基于索引的数据访问
    表关联的方式
        NL
        MJ
        HJ 
        
hints的使用范畴
    -尽量避免在开发中使用
    -辅助dba用来做性能排查
    
访问路径相关的hints 
/* full */全表扫描
--全表扫描可以多块读的方式
--全表扫描可以用并行
SQL> explain plan for
  2  select /* full(t) */ * from t where id < 8;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     3 |    78 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |     3 |    78 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("ID"<8)
Note
-----
   - dynamic sampling used for this statement (level=2)
 
17 rows selected

--index no_index 
/* index(t id) */ 使用索引
/* no_index(t id) */ 不适用索引
/* index_ffs */ 与全表扫描机制相似 索引快速全部扫描 
/* + index_ss */ index skip scan 
    -用于替代全表扫描的一种数据访问方法
    -对于前导重复率高的联合索引 index skip scan性能好一些 

===============
11 hints 
/*+ use_nl */ nested loop joins 
--两个结果集的关联 
--内部表外部表 从一张表取数据与另外一张表取
--nl的场景
--关联中有一个表比较小
--被关联表的关联字段上有索引
--索引的键值不应该重复率高
--小表作为外部表 小表去大表进行关联 
SQL> explain plan for
  2  select /*+ use_nl(t,t2) */ t.*
  3    from t,t2
  4   where t.id = t2.id ;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 125942274
--------------------------------------------------------------------------------
| Id  | Operation                    | Name        | Rows  | Bytes | Cost (%CPU)
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |             |     5 |   195 |     8   (0)
|   1 |  NESTED LOOPS                |             |       |       |
|   2 |   NESTED LOOPS               |             |     5 |   195 |     8   (0)
|   3 |    TABLE ACCESS FULL         | T2          |     5 |    65 |     3   (0)
|*  4 |    INDEX UNIQUE SCAN         | SYS_C003776 |     1 |       |     0   (0)
|   5 |   TABLE ACCESS BY INDEX ROWID| T           |     1 |    26 |     1   (0)
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("T"."ID"="T2"."ID")
Note
-----
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
   - dynamic sampling used for this statement (level=2)
 
21 rows selected

/*+ use_hash */ hash join 
--原理:oracle把小的表数据集hash到内存中 hash成多个分区 内存放不下放到临时表空间
--大的表把关联的字段hash 大的hash匹配小的的hash 
--hash join的应用场景
    --一个大表,一个小表关联
    --表上没有索引
    --返回结果集比较大 
SQL> explain plan for
  2  select /*+ use_hash(t,t2) */ t.*
  3    from t,t2
  4   where t.id = t2.id ;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 106979157
---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     5 |   195 |     7  (15)| 00:00:01 |
|*  1 |  HASH JOIN         |      |     5 |   195 |     7  (15)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T    |     5 |   130 |     3   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| T2   |     5 |    65 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T"."ID"="T2"."ID")
Note
-----
   - dynamic sampling used for this statement (level=2)
 
19 rows selected

/*+ usr_merge */ sort merge join 
--两个结果集先排序再进行关联
--应用场景
--当结果集已经排序
SQL> explain plan for
  2  select /*+ use_merge(t,t2) */ t.*
  3    from t,t2
  4   where t.id = t2.id ;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1077318368
----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     5 |   195 |     8  (25)| 00:00:01 |
|   1 |  MERGE JOIN         |      |     5 |   195 |     8  (25)| 00:00:01 |
|   2 |   SORT JOIN         |      |     5 |   130 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T    |     5 |   130 |     3   (0)| 00:00:01 |
|*  4 |   SORT JOIN         |      |     5 |    65 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| T2   |     5 |    65 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   4 - access("T"."ID"="T2"."ID")
       filter("T"."ID"="T2"."ID")
Note
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement (level=2)
 
22 rows selected

/*+ leading() */ 规定表连接的顺序
--驱动表 被驱动表 不加是由优化器决定
SQL> explain plan for
  2  select /*+ leading(t,t1,t2) */ t.*
  3    from t,t1,t2
  4   where t.id = t2.id
  5     and t.id = t1.id;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2090431216
----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |     5 |   260 |    10  (10)| 00:00:01 |
|*  1 |  HASH JOIN          |      |     5 |   260 |    10  (10)| 00:00:01 |
|*  2 |   HASH JOIN         |      |     5 |   195 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| T    |     5 |   130 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL| T1   |     5 |    65 |     3   (0)| 00:00:01 |
|   5 |   TABLE ACCESS FULL | T2   |     5 |    65 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("T"."ID"="T2"."ID")
   2 - access("T"."ID"="T1"."ID")
Note
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
-----
   - dynamic sampling used for this statement (level=2)
 
22 rows selected

/*+ append */ 以直接加载的方式插入数据
--传统加载:在高水位下有空的加载数据
--直接加载:append在高水位上加载,然后移动高水位
--append有时候会减少redo 
--当数据是归档,产生日志 产生redo 
--数据归档 不产生日志 不产生redo 
--非归档 都不产生redo 
alter table t nologging;  --设置为不产生日志
insert into t select * from t;
insert /*+ appedn */ into t select * from t;
--比较两个产生的redo 

--设置动态采样的级别
/* dynamic sampling */ 
--采样率越高越准确,消耗的资源越多
select /*+ dynamic sampling(4) */ count(*) from t;

--指定并行度
/*+ parallel */ 
SQL> explain plan for
  2  select /*+ parallel(t 2) */ count(*) from t;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3126468333
--------------------------------------------------------------------------------
| Id  | Operation              | Name     | Rows  | Cost (%CPU)| Time     |    T
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |          |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE        |          |     1 |            |          |
|   2 |   PX COORDINATOR       |          |       |            |          |
|   3 |    PX SEND QC (RANDOM) | :TQ10000 |     1 |            |          |  Q1,
|   4 |     SORT AGGREGATE     |          |     1 |            |          |  Q1,
|   5 |      PX BLOCK ITERATOR |          |     5 |     2   (0)| 00:00:01 |  Q1,
|   6 |       TABLE ACCESS FULL| T        |     5 |     2   (0)| 00:00:01 |  Q1,
--------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
 
17 rows selected

/*+ driving_site() */ 
--决定一个分布式事务中,操作在那个节点上完成 
select /*+ driving_site(departments) */ * 
  from employees,departments@rsite 
 where employees.department_id = departments.department_id;
 
--如果没有hint,远程表上的数据将被传到本地来做关联
--使用hint,本地的数据将传到远程节点上执行,最后将结果返回本地

/*+ cardinality() */ 
--模拟一个结果集的cardinality 
--t表返回100条数据 
select /*+ cardinality(t 100) */ *
  from t,t1 
 where t.object_id = t1.object_id 
   and t.object_id >  100 
   
==========
13 等待事件 
sql*net message from client 
--oracle一个通信协议
--空闲等待
--客户端和数据端建立好了连接,等待客户端发送指令
SQL> select distinct sid from v$mystat;
 
       SID
----------
        26
 
SQL> select sid,event,state from v$session where sid=26;
 
       SID EVENT                                                            STATE
---------- ---------------------------------------------------------------- -------------------
        26 SQL*Net message from client 

造成oracle的等待,三种情况
    请求的资源太忙,需要等待资源释放
    会话处于空闲状态,等待新的任务
    会话被阻塞,需要等待阻塞解除 
    
1.数据库处理数据,只有有时间消耗,就会有等待事件
2.性能和等待是一个矛盾体
3.理解出现某种等待时间的原因
4.结合业务,主观的看待等待事件
    -制定基线(baseline)发现异常等待事件
    -接受合理的等待事件 
    
等待的定位方式 sql级别
10046 event 

会话级别 动态视图
    v$session_wait 
begin 
  for i in 1..1000 loop 
    insert into t select * from dba_objects;
  end loop;
end;
/

select sid,enent from v$session_wait where sid = 22;

系统级别 AWR报告

等待事件的分类

查看等待事件 
v$session_wait 会话级别 
SQL> select event,p1,p1text,p2,p2text,p3,p3text from v$session_wait where sid=26;
 
EVENT                                                                    P1 P1TEXT                                                                   P2 P2TEXT                                                                   P3 P3TEXT
---------------------------------------------------------------- ---------- ---------------------------------------------------------------- ---------- ---------------------------------------------------------------- ---------- ----------------------------------------------------------------
SQL*Net message from client                                      1413697536 driver id                         
p1 文件id 
p2 数据块号
p3 读取的数据块号 

常见的等待事件 
ilde wait events 
    进程无事可做,等待分配任务
    空等待意味着空闲,还意味着其它 
CPU不属于等待事件 
    select name,value from v$sysstat where name like %CPU%;
db file scattered read 数据多块读
    当数据块以multiblock read 的行式被读取到sga中时
     -FTS full table scan 
     -IFFS index fast full scan 
     -db_file_multiblock_read_count 每次读取多少块的参数
     解决:
        -无需解决
        -考虑索引
        -考虑并行 
db file sequential read 顺序的读 
    当把数据块读入aga时,发生db file sequential等待
    单数据块的读,通常指索引的读取
        有些索引读取会发生db file scattered read 等待
        有时候表的读取 有很多extend 边界
        undo的读取 一个块一个块的读 
    解决:
        -无需解决
        -sql语句的效率
        -考虑其它方式的索引
            复合索引
            位图索引
            全文索引
        -全表扫描+并行
        -改善磁盘I/O 
direct path read 直接路径数据读 
    排序数据内存不足,被写到磁盘上,重新读取
    并行操作的slave进程的数据读取
    其它的属于某个会话私有数据的读取
  参数说明:
    p1 p2 p3 
  解决:
    增大内存排序区 pga 
    调整并行度
    改善磁盘I/O 
direct path write 同上 
log file sync log文件的同步
    用户commit(rollback)时,lgwr需要将log buffer的数据写道log file上面,发生等待
    解决:
      -减少commit的频率 错误的频繁提交
      -提高I/O性能 
buffer busy waits 数据块繁忙等待
    内存中对相同的数据块有多个并发请求,导致这个等待
    参数说明:
      p1 读取数据快所在的文件id
      p2 读取的数据块id 
      p3 等待类型 class id 
    解决:
      -热块 
        segment header -ASSM 自动断管理
        data block -ASSM 反向索引
        undo header -automatic undo management 
        undo block -增大回滚段
free buffer waits 申请空闲的buffer
    -系统I/O成为瓶颈 或者性能不够
    -等待资源latch争用 
    -sga太小
    -sga太大,dbwr无法快速的把脏数据刷到磁盘上 
    优化I/O 
      -提高I/O通道的性能
      -异步I/O 
      -增加多个dbwr进程
    增大sga 
    
相关的视图 
    v$session_event 记录会话所有等待信息 
    v$system_event 实例级别的视图 
    
============
15 索引与分区
索引的目的
    提高数据访问的效率
比较索引和直接读
consistent gets 一次性读

oracle的索引类型
    B-tree索引 B树索引
      根 -- 叶 
      高效场景
        -索引字段有着很高的selectivity或者结果集很小的时候
      低效场景
        -索引字段有着很低的selectivity或者结果集很大的时候
      基本适用所有类型的数据库
      没有明显的缺点
    Bitmap索引 位图索引
      每条记录记录一个状态 位运算 不占空间
      位图索引的运算就是计算机的位运算
      场景
        -OLAP
        -重复率高的键值 
        -and or 运算 
      不适用的场景
        -OLTP
        -DML频繁操作
      位图索引的锁定
        更新一条记录会锁定另外的记录 更新同一个键值 
        DML操作会影响位图段
        在有bitmap的表中修改数据,会对所有受影响的键值关联的记录做锁定
    TEXT index 全文索引 又叫模糊查询
      create index idx_t on(object_name) indextype is ctxsys.context
      select count(*) from t where contains(object_name,TABLE)>0;
      全文索引是如何存储数据的
        -查看索引
        select table_name,index_name from user_indexes;
        select segment_name from user_segments where segment_name=IDX_T;
          -并不占用空间
        使用场景
          -b-tree,bitmap无法发挥作用的场景
          -模糊查询 like %string% 
        缺点
          -占用过大的磁盘空间
          -维护成本高
          -bug多
        查看表大小
          select bytes/1024/1024 from user_segments where segment_name=T;
          
==================
16 分区
分区表
    -表分区后,分区变成各自的段,表是一个逻辑名称
    -分区剪裁 表属于一个段 段属于一个表空间 
    -性能 数据管理 
  非分区表:扫描所有
  分区表:范围扫描
分区的分类
  list分区
    -区域 地址 part_date 
  range 范围分区 
    -时间 月
  hash 哈希分区 
  组合分区(子分区)
    先按列表分区再按范围分区
      -range-range 
      -list-range
      -list-hash
      -list-list 
分区索引
  local index 
    -表的DML操作无需rebuild索引
    -可以非常方便的管理数据 
  全局索引
    -表的DDL操作会导致索引无效
误区:分区索引性能好于全局索引
  create index idx_t on t(id); --全局索引
  create index idx_t on t(id) local;
总结:
    1.分区索引的目的在于数据的管理而非性能
    2.一个分区表上如果经常有DDL操作,将会导致全局索引失效,需要对索引重建,此时创建分区索引更加合适
    
===========
17 数据分析
CBO的数据来源
  -CBO是一个数学模型
  -需要准确的传入数据
  -通过精确的数据计算出精确的执行计划 


当没有分析数据时 
    create table t as select * from dba_objects;
    select extents,blocks from user_segments where segment_name=T;
    select num_rows,blocks from user_tables where table_naem=T;
    没有分析数据时会自动进行动态采样
    select /*+ dynamic_sampling(t 0) */ count(*) from t;
      -将动态采样设为0 
分析信息部充足 
    update t set object_id=1 where object_id<1001;
    exec dbms_status.gather_table_stats(user,t,method_opt=>for all columns size 1);
    --不收集直方图信息
    select * from t where object_id=1;
充足数据
    exec dbms_status.gather_table_stats(user,t,method_opt=>for all columns size 256);
    
CBO的数据来源
  初始化参数
    -优化参数
    -CPU 
    -数据块大小
    -多块读的大小
  数据字典
    -user_tables,user_tab_partitions 
    -user_indexes,user_ind_partitions 
    -user_tab_col_statistics 
    
DBMS_STATS包和analyze命令
analyze命令已经过时
  -无法提供灵活的分析选项
  -无法提供并行的分析
  -无法对分析数据进行管理
DBMS_STATS 
  -专门为CBO提供信息来源
  -可以进行数据分析的多种组合
  -可以对分区进行分析
  -可以进行分析数据管理
  
oracle的自动信息收集
  -oracle11g的一个默认设置
  -user_tab_modification跟踪表的修改
  -当分析对象的数据修改超过10%时,oracle会重新分析
  -定时任务GATHER_STATS_JOB负责重新收集过旧数据的信息
  exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO;  --刷新
  select inserts,updates,deletes,timestamp from user_tab_modifcations where table_name=T;
  --查看状态
  select log_id,job_name,status,log_date
    from dba_scheduler_job_run_details
   where job_name = GATHER_STATS_JOB;
   
是否完全依赖自动分析
  1.当数据执行计划保持不错的时候,可以依赖自动分析
    -OLTP系统
  2.需要手工介入 
    -OLAP系统
  3.没有一个适合所有系统的数据分析方法
  
手工分析
DBMS_STATS包
  -Gathering_optimezer_statistics 收集
  -setting_or_getting_statistics 自己设置参数 
  -deleting_statistics 删除
  -transferring_statistics 传输
  -locking_or_unlocking_statistics 锁定
  
表数据的收集 
DBMS_STATS.GATHER_TABLE_STATS(
 ownname
,tabname
,partname
,estimate_percent 采样
,block_sample 块的采样
,method_opt default for all columns size
,degree 并行
,granularity 粒度
,cascade 索引
,stattab 建表存储统计信息
,statid
,statown
,no_invalidate 验证有效性
)
  procedure gather_table_stats
    (ownname varchar2, tabname varchar2, partname varchar2 default null,
     estimate_percent number default DEFAULT_ESTIMATE_PERCENT,
     block_sample boolean default FALSE,
     method_opt varchar2 default DEFAULT_METHOD_OPT,
     degree number default to_degree_type(get_param(DEGREE)),
     granularity varchar2 default  DEFAULT_GRANULARITY,
     cascade boolean default DEFAULT_CASCADE,
     stattab varchar2 default null, statid varchar2 default null,
     statown varchar2 default null,
     no_invalidate boolean default
       to_no_invalidate_type(get_param(NO_INVALIDATE)),
     stattype varchar2 default DATA,
     force boolean default FALSE);

索引数据的收集
DBMS_STATS.GATHER_INDEX_STATS
    (ownname varchar2, indname varchar2, partname varchar2 default null,
     estimate_percent number default DEFAULT_ESTIMATE_PERCENT,
     stattab varchar2 default null, statid varchar2 default null,
     statown varchar2 default null,
     degree number default to_degree_type(get_param(DEGREE)),
     granularity varchar2 default DEFAULT_GRANULARITY,
     no_invalidate boolean default
       to_no_invalidate_type(get_param(NO_INVALIDATE)),
     stattype varchar2 default DATA,
     force boolean default FALSE);
      
数据分析示例:
  exec dbms_stats.gather_table_stats(user,t);  --表分析
  exec dbms_stats.gather_index_stats(user,idx_t);  --索引分析 
  
  --对表分析带对索引分析
  exec dbms_stats.gather_table_stats(user,t,cascade=true);

重要的参数:
  estimate_percent 采样百分比
    -DBMS_STATS.AUTO_SAMPLE_SIZE 
    -手工设置(范围:0.000001,1001.超大表 0.000001
      2.大表
      3.小表 
  granularity 数据分析的力度 在什么层面上 针对分区表
    -global 
    -partition
    -subpartition 
    示例:
     create table t(id int,name varchar2(1000))
     parttion by range(id)
     (partition p1 values less than(10000),
      partition p1 values less than(10000),
      partition p1 values less than(10000),
      partition pmax values less than(maxvalue))

     exec dbms_stats.gather_table_stats(user,t);
     select partition_name,blocks,num_rows,golbal_stats from user_tab_partitions where table_name=T;
     insert into t select object_id,object_name from dba_objects;
     exec dbms_stats.gather_table_stats(user,t,granularity=>partition);
     select partition_name,blocks,num_rows,golbal_stats from user_tab_partitions where table_name=T;
     select count(*) from t where id<10000;  --分区统计信息
     select count(*) from t where id<30000;  --全局统计信息 全局信息没有收集
     select count(*) from t where id<10001;  --跨分区 使用全局统计信息 

全局分析和分区分析
    当表上已经有全局统计信息时,单独对分区分析,不会更新全局信息
    分区的合并
    
=============
18 全局分析和分区分析 
分区和全局信息 
  增量统计(oracle11g)
    -oracle会增量的收集分区信息来更新全局信息
    -配置
    exec dbms_stats.set_table_prefs(user,t,INCREMENTAL,TRUE);
  如何设置这个参数
    -在一个很大的分区表(OLAP),全局分析代价非常昂贵
    -OLAP系统下,除了新加入的数据,旧的数据基本上没有变化,全局分析乱费资源
    -对于很大的分区表 incremental(oracle11g)
    -对于不大的分区表,可以使用默认设置 

参数:
  method_opt 分析直方图选项 
  直方图:
    oracle对列上的数据分布进行统计分析,对数据倾斜分布时有用
    Frequency  -频率直方图 
      -字段上键值重复率高
    height-balanced 高度平衡直方图
      -把数据装入每个桶中,量一样,值不一样
      -装入的数据量相同(数据条数),键值不同
      
      -size 12 相当于设置多少个桶 最大254 
      例:
      create table t as select object_id col1,trunc(rownum/1000) col2 from dba_objects where rownum<10000;
      exec dbms_stats.gather_table_stats(user,t,method_opt=>for all columus size 12);
      --
      select colume_name,num_distinct,num_buckets,histogram from user_tab_col_statistics 
      where table_name=T and column_name=COL1
      select endpoint_number,endpoint_value from user_tab_histograms 
      where table_name=T and column_name=COL1
      
    设置:
      1.for all columns 统计所有列的histograms
      2.for all indexed columns 统计所有indexed列的histograms 
      3.for all hidden columns 统计你看不到列的histograms 
      4.for columns <list> size <n> |repeat|auto|skewonly:
        -N的取值范围[1,254]
        -repeat 上次统计过的histograms 
        -auto 由oracle决定N的大小
        -skewonly 只收集非均匀分布的直方图,系统决定桶数
        
列的相关性 扩张的统计
extended statistics 
  select count(*) 
    from sh.customers 
   where cust_stats_province=CA;
     and country_id=52775 
  --实际结果与执行计划差别较大
   country_id=52775 
   country_id=52790
  EXEC DBMS_STATS.GATHER_TABLE_STATS(
  SH
 ,CUSTOMERS
 ,METHOD_OPT=>FOR ALL COLUMNS SIZE SKEWONLY 
  FOR COLUMNS (CUST_STATE_PROVINCE,CONUTRY_ID) SIZE SKEWONLY  --列的相关性分析
  )
    
动态采样
  当表上没有分析信息时,oracle会使用动态采样技术
  发生在sql解析时(硬分析)有限的数据块
  不同级别,采样的数据块数量不同
    -level 1-10 采样数据量逐级递增
    -level10 对所有数据进行采样分析
  1.动态采样只能作为一种辅助手段
  2.海量数据,动态采样的数据块太少,无法准确的反映数据的真实情况
  3.采样率高,会影响sql的执行效率
  4.dbms_stats可以非常灵活的进行数据分析配置
    -分析比例
    -分析时间
    -直方图
    -分析数据的管理

==============
19 并行
  将一件工作分成很多块,分别由不同的进程来执行,最后将结果合并
  应用场景:
    1.OLAP数据仓库
      -OLAP是一个业务模型
      -数据仓库 用于支撑的数据库
    2.整块的数据读取操作
      -FTS 全表扫描 
      -IFFS 
    3.并行执行高效的要素
      -充足的系统资源
      -待处理的数据分布均匀
  
  并行的机制
    用户连接到数据库 - 启动相应的server process - 用户发出并行server process变成并行协调进程(qc)
    select /*+ parallel(c,2) */ *
      from customers 
     order by cust_last_name,cust_first_name 
    每步启动两个进程 
  并行的执行计划
    SQL> explain plan for
  2  select /*+ parallel */ *
  3    from t
  4   order by id;
 
Explained
SQL> select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 3122197462
--------------------------------------------------------------------------------
| Id  | Operation               | Name     | Rows  | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT        |          |     5 |   130 |     3  (34)| 00:00:
|   1 |  PX COORDINATOR         |          |       |       |            |
|   2 |   PX SEND QC (ORDER)    | :TQ10001 |     5 |   130 |     3  (34)| 00:00:
|   3 |    SORT ORDER BY        |          |     5 |   130 |     3  (34)| 00:00:
|   4 |     PX RECEIVE          |          |     5 |   130 |     2   (0)| 00:00:
|   5 |      PX SEND RANGE      | :TQ10000 |     5 |   130 |     2   (0)| 00:00:
|   6 |       PX BLOCK ITERATOR |          |     5 |   130 |     2   (0)| 00:00:
|   7 |        TABLE ACCESS FULL| T        |     5 |   130 |     2   (0)| 00:00:
--------------------------------------------------------------------------------
Note
-----
   - dynamic sampling used for this statement (level=2)
   - automatic DOP: Computed Degree of Parallelism is 2
 
19 rows selected

===============
20 并行与性能
  并行度,oracle进行并行处理时,会启动几个并行进程来同时执行
  并行度的设定
    -elaspend time 
    -system cpu time 
    -system wait cpu time 
   获得sql的并行度
     v$px_session.degree 
     v$pq_tqstat 
     10391事件 
  并行相关的初始化参数
    parallel_degree_limit
    parallel_degree_policy
    parallel_force_local
    parallel_min_time_threshold
    parallel_servers_target
    parallel_execution_message_size
    
    parallel_degree_policy 
     -manual(default)
     -limited
     -auto 
  并行用途
    并行DDL操作
      -create table ...as select 
      -alter table move partition 
    并行DML(分区表)
      -update
      -delete
      -merge 
     
===========
21 变量绑定
select * from t where id=:B;

begin 
  for i in 1..4 loop
    execute immediate select * from t where rn=:i using i;
  end loop;
end;

变量绑定的目的
  1.减少sql硬解析的次数
  2.减少系统资源开销
  3.减少latch争用 
应用场景:
  1.适用于OLTP
    -用户并发很高
    -表中有主键
    -操作的数据少
    -执行计划基本相同
    -sql重复率高
     
  2.不适用OLAP
    -执行计划多变
    -用户少
    -sql解析对系统性能影响小

sql语句的处理
  硬分析(hard parse)
    -语法解析 
    -语义分析 表是否存在
    -shared pool chech 
    当sql语句第一次执行时,都会被硬解析 
  软解析(soft parse)
    -共享池中搜索执行计划
    -使用现有执行计划执行sql 
    alter system flush shared_pool;  --刷新shared_pool
  会话对游标的缓存(softer_soft_parse)
  session_cached_cursor
    -对于已经关闭的cursor,可以把它的资源保留在pga中,后续对cursor继续调用
    -如果该参数设置为0,oracle将会对关闭的游标重新打开
    
父子游标
  同样的sql,会产生另外的cursor 
    -父游标parent cursor  第一条运行的sql
    -子游标 child cursor 后续的sql 
    select sql_id,child_number,sql_text
      from v$sql 
     where sql_text=select * from emp where 1=0;
     
    select sql_id,auth_check_mismatch 
      from v$sql_shared_cursor
     where sql_id = ‘‘;
     
============
22 游标及共享
游标共享 cursor_sharing 
alter session set cursor_sharing=EXACT;  --共享游标设置
cursor_sharing=force  --强制绑定
cursor_sharing=similar  --有不同的执行计划 生成两个游标

bind peeking 变量窥视
oracle在第一次解析sql时,如果sql上有变量绑定,会查看这个变量的值,准确的指定执行计划;
后续的分析中,将不会理会这个变量的值
使用场景
  -执行计划机会不改变
  -大量的并发
  -大量的除谓词外机会相同的sql 
不适用的场景 
  -执行计划会随变量值的变化而变化
  -少量的sql   

adaptive cursor sharing(ACS)
  通过不断观察bind的值,来决定新的sql是否使用之前的执行计划,解决绑定变量导致后续执行计划不变的问题
  缺点:
    -更多的硬分析
    -产生更多的子游标,需要更多的内存
    -消耗更多的CPU
  oracle使用ACS的前提条件:
    绑定变量使用bind peeking 
    绑定变量的列上有直方图
    
  清理两次共享池?oracle11g 

===============
23 sqltrace 
用以描述sql的执行过程的trace输出
  -sql是如何操作数据的
  -sql执行过程中产生了那些等待时间
  -sql执行中消耗了多少资源
  -sql的实际执行计划
  -sql产生的递归语句 

set auto trace(explain plan) 
  -输出优化器的产生的执行计划(估算值)

sql_trace 
  sql的实际执行情况
    -消耗的资源
    -产生的等待事件
    -数据的处理过程 
    ...
    
当需要分析执行计划及CBO行为时,使用 set auto trace(explain plan)
当要看一条sql的真实运行效果时,使用 sql_trace(10046)

产生一个sql_trace 
alter session set sql_trace=true;
select count(*) from t;
alter session set sql_trace=false;

select * from v$diag_info where name like Default%;

阅读原始的trace文件
parsing in cursor部分
len -长度
dep -递归深度
uid -user id 
otc -oracle command type 命令的类型
lid -私有的用户id 
tim -时间戳
hv -hash value 
ad -sql adress 

parse,exec,fetch部分
c -消耗的cpu time 
e -elspsed time 操作的用时
p -physical reads 物理读次数
cr -consistent reads 一致性方式读取的数据块
cu -current 方式读取的数据块
mis -cursor miss in cache 硬分析次数
r -rows 处理的行数
dep -depth 递归sql的深度
og -optimizer goal 优化器模式
tim -timstamp 时间戳 

stats部分
id -执行计划的行源号
cnt -当前行源返回的行数
pid -当前行源号的父号
pos -执行计划中的位置
obj -当前操作的对象id
op -当前行源的数据访问操作

tkprof -格式化trace文件的工具
  tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4271.trc out.txt
  --去除递归
  tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4271.trc nosys.out sys=no 
  --添加优化器执行计划
  tkprof /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4271.trc exp.out explain=test/test;

tkprof报告中的数据块的两种读取方式

============
24 trace事件和10046事件 
跟踪其它会话的sql 
grant execute on dbms_system on test;
select distinct sid from v$mystat;
select sid,serial# from v$session where sid=27;
execute sys.dbms_system.set_sql_trace_in_session(27,60,TRUE);
--描述性语言
select /*+ trace_by_other_session */ count(*) from t;
execute sys.dbms_system.set_sql_trace_in_session(27,60,false);

第三方软件
  -toad
  -pl/sql developer 
  
10046 event 
alter session set events 10046 trace name context forever.level n;
  -level 1 等同于sql_trace的功能
  -level 4 在level 1的基础上增加收集绑定变量的信息
  -level 8 在level 1的基础上增加等待事件的信息
  -level 12 等同于level 4+level 12,同时收集绑定变量和等待时间信息
  
  variable x number;
  exec :x:=1;
  alter session set events 10046 trace name context forever.level 1;
  select count(*) from t where object_id = :x;
  alter session set events 10046 trace name context off;
  
  dbms_system.set_ev(sid,serial#,10046,0,username);
    exec dbms_system.set_ev(135,694,10046,12,‘‘);
    
=============
10053 事件 
  了解oracle执行计划的生成过程
  无法获知代价的计算公式 
  sys.dbms_system.set_ev(sid,serial#,10053,1|2|0)
  
  create table t as select * from t1 where rownum<100;
  create index idx_t on t(object_id);
  create index idx_t1 on t1(object_id);
  
  begin 
    dbms_stats.gather_table_stats(
    user,
    t,
    cascade=>true,
    estimate_percent=>null,
    method_opt=>for all columns size 1
    );
   end;
   /
   
   alter session set events 10053 trace name context forever,level 1;
   select count(*) from t,t1 where t.object_id=t1.object_id;
   
10053 trace的内容
参数区
sql区 
系统信息区 system statistics information 
基本统计信息 base statistical information 
数据访问 access path 
关联查询 join order 
代价的最后修正
最终执行计划
 
当set autotrace 或者explain plan显示错误的执行计划,而找不到原因 

============
初始化参数和性能视图 
性能问题的来源和对应的性能视图
  CPU 
    cpu_count 逻辑cpu数量(thread)
    对并行和代价有影响
  内存
    memory_target 自动管理内存特性
    memory_max_target 
    sga_target 
    pga_aggregate_target pga内存空间总和动态调整
  I/O 
    db_file_multiblock_read_count 多块数据的读取
    --多块读只在下面两种情形下
        FTS
        index ffs 
    db_writer_processes 
      设置多个db_writer进程,加快数据从缓冲区写入磁盘的速度
    disk_asynch_io 
  网络
    processes 允许产生的process数量
    sessions 允许产生的session数量
    process和session的关系
      -process表示操作系统级别的一个进程
      -session 表示process和数据库建立的会话数量 
    open_cursors 
      某个会花能够打开的最大游标数 
      默认值50 取值0-65535 
  优化器 
    optimizer_index_cost_adj CBO计算成本时索引的权重修正值
    
性能视图 
CPU 
  -v$sysstat 
  -v$sesstat 某个会话消耗cpu的值
内存 
  -v$memory_target_advice oracle自动管理内存的建议器 
  -v$sga_target_advice
  -v$pga_target_advice
  -gv$shared_pool_advice 
I/O 
  -v$iostat_file 
    显示各种文件的I/O统计信息 
    数据文件,临时文件,控制文件,日志文件,归档文件
对象
  -v$segstat 获得某对象的各类统计信息 
网络会话 
  -v$session 某会话的当前各种状态,比如关联v$sql视图查看当前会话的sql语句
  -v$session_wait 会话当前等待事件的详细信息
  -v$session_event 会话所有等待事件的详细信息
  -sesstat 会话的资源统计信息 
  
================
AWR & ASH报告
automatic workload repository(AWR)

AWR报告的信息来源
  select table_name from dict where table_name like DBA_HIST_%;
  
手工统计AWR数据
  select snap_id,name,value from dba_hist_sca where snap_id>=1178 and snap_id<=1180;
  
生成AWR图形曲线
  DBA_HIST --> ODBC -->EXCEL 
 
AWR in Enterprise Manager 企业管理器 

AWR基线(baseline)
 dbms_workload_repository.create_baseline()
 
AWR报告生成 
  $ORACLE_HOME/rdbms/admin 
  awrrpt.sql 
  
  @/u01/app/oracle/product/11.2.0/dbhome_1/rdbms/admin/awrrpt.sql

  --header 
  --load profile 负载
  --top 5等待事件 
  --cpu & memory 
  --RAC信息
  --time model statistics 
  --foreground wait 前台
  --background wait events 后台
  --instance axtivity statistics 实例 
  --tablespace IO statistics 
  --buffer pool advisory 
  --pga advisory 
  --latch statistics 
  --segments access statistics 
  
AWR报告的阅读方法
  1.了解数据库和业务情况
  2.有侧重点的阅读
  3.按照一条线索来阅读
  4.面-线-点的方式 
  
==================
ASH active session history 
  ASH报表间隔时间可以精确到分钟,因而ASH可以提供比AWR更详细的关于历史会话的信息,可以作为AWR的补充
  信息来源:
    -v$active_session_history 当前会话的采样数据,1秒钟一次快照
    -dba_hist_active_sess_history (保留v$active_session_history更早的历史数据) 
    
    ASH AWR SQL_TRACE 
    
    产生ASH报告
    运行 ashrpt.sql 
    
    通过sql查询性能差的sql 
      select sum(a.time_waited) total_time
        from v$active_session_history a,
             v$event_name b 
       where a.event# = b.event# 
         and sample_time > 21-nov-18 12:00:00 AM 
         and sample_time < 21-nov-18 05:00:00 AM
         and b.wait_class = USER I/O 
    
    ASH报告 
      -top user events 
      -top events 等待事件的明细
      -top sql 
      -top sessions 
      -top objects & files 
      
AWR & ASH 
  1.对业务了解
  2.建立基线数据做对比
  3.有目的性的阅读
 

 

以上是关于oracle性能优化的主要内容,如果未能解决你的问题,请参考以下文章

Oracle性能优化之性能调整_超越OCP精通Oracle视频教程培训38

Oracle性能优化之性能诊断工具_超越OCP精通Oracle视频教程培训33

Oracle Proc编程性能优化经验

Oracle性能优化之性能跟踪工具_超越OCP精通Oracle视频教程培训34

Oracle性能优化之操作系统工具_超越OCP精通Oracle视频教程培训37

Oracle性能优化之执行计划管理_超越OCP精通Oracle视频教程培训31