<<让oracle跑的更快读书笔记1>>
1 锁和阻塞
1) 当一个表有主键唯一时,一个会话在更新后,如果没COMMIT,另外一个会话也出更新
,则会发生死锁
2)查看:
select sid,type,id1,id2,lmode,request,block from v$lock where sid in
(xxx,yyy) order by sid;
其中block列=1表示这个会话正在阻塞另外一个会话;request中的值表示当前会话正
在等待另外一个lmode=XX
的锁
通过SID,可以查询出锁定的用户信息
select machine from v$session where sid in (xx,yyy0;
3)当一个表有若干分区或段的时候,每个都会加上TM表锁,比如一个表某个段加了TM
锁,则不能在其上进行DDL操作,但可以在其他分区段上进行。
4)可以通过select ...for update里阻挡另外的会话对其进行修改
5)主从表的关联查询情况,从表上的外键应该创建索引
2 LATCH和等待
当一个数据块正在被一个会话从磁盘中读到内存中时,如果另外一个会话也要读取
,则必须有机制来处理,
可以把latch理解为轻量级的锁,不会造成阻塞只会导致等待。
1)共享池中的latch争用
如果有大量的SQL被反复分析,就会造成大的latch争用
select * from v$latchname where name like 'library cache%'
2) 访问频率很高的数据块被称为热块,很多用户一起访问时,导致latch争用
当一个会话需要访问一个内存块,先要去象链表一样的结构去搜索这个数据快是否
在内存中;
当一个会话需要访问一个数据块,而这个数据块正在被另外一个用户从磁盘读取到内存中
或者正在被会话修改时,当前的会话需要等待,就产生buffer busy waits等待
A 表数据块
对于一些小表,如果频繁修改,则变成热块,可以考虑将表数据分布在更多的数据
块上,减少
数据块被多数会话同时访问的频率
alter table minimize records_per_block;
但会降低数据读取的性能
B 索引数据块
在RAC中,如果表的主键用序列递增,则多用户在RAC的不同实例中插入时,
会出现相同索引数据块在不同实例的内存中被调用,形成争用,可以使用反向索引;但会
降低性能,在范围查询时要走全表扫描
C 索引根数据块
热块可能发生在索引的根数据块中,可以把索引创建为分区索引时,索引的
根数据块会分布到更多的数据块中。
D 段头数据块
ASSM,让oracle自动管理"free lists",所谓的free lists,是每个数据段的段头
有几个free list列表,存放哪些数据块可以用,当数据块的数据达到一个比例
(pct_free)时,数据块就会从free list中删除,这个数据块不能再插入数据。
3 优化器
10G中,使用CBO(基于代价的),不用RBO(基于规则的)
当没做表分析时,会动态采样分析统计的信息,只发生在第一次,后续的不再使用
动态分析,而使用第一次硬分析时生成的计划。
CBO两种运行模式
1)first_rows(n)
2)all_rows
first_rows(n):优先返回结果集中的前n条记录以最快速度反馈回来
all_rows:意味将用最快的速度将SQL执行完,将结果集全部返回。
先创建plan_table 表
SQL>@%oracle_home%/rdbms/admin/utlxplan.sql
授权
SQL>@%oracle_home%/sqlplus/admin/plustrce.sql
这样普通用户不能用
所以要授权普通用户对 plan_table 表
SQL>conn / as sysdba
SQL>create public synonym plan_table for plan_table;
SQL>grant all on plan_table to public;
开启查询计划
SQL>set autotrace on --显示执行计划和统计信息
SQL>set autotrace on explain --只显示执行计划
SQL>set autotrace on statistics --只显示统计信息
SQL>set autotrace traceonly --同autotrace on,但不显示查询结果
SQL>set autotrace off --关闭autotrace
select /*+ dynamic_sampling(t 0) */ * from t where ...
/*+ dynamic_sampling(t 0) */ 禁止表用动态采样查询
要注意的是,在对数据UPDATE或更新后,如果不对表进行分析,表中的分析
数据CBO的,还是旧的信息,要对表进行更新。
在用explain plan for ...SQL语句后
如果发现predicate information中:
filter:类别的,表示谓词的条件值不会影响数据访问路径,只起到筛选作用;
而
access:表示谓词的条件值会影响访问路径,比如是用索引还是全表扫描。
记得如果表分析过,但数据变了,而没重新分析,则会导致错误的执行计划;
4 HINT
如果在表中指定了别名,则hint中也要使用别名,否则CBO会忽略
select /*+ full(a) */ count(*) from t a;
系统级别设置优化器: