又是latch: cache buffers chains惹得祸
前言
一大早,客户给我打电话说:
xx,应用很慢,查询数据总是超时,让我看看。。。
根据多年DBA经验,首当其冲的肯定是去查询数据库在这段时间都在干嘛。
分析
导出awr报告分析
1). 数据库在此时间段非常繁忙。
2). 查看Top 5 Timed Events,出现了Concurrency等待事件latch: library cache**
3). 查看SQL ordered by Gets,不看不知道,一看吓一跳
4). *50pwxa3bzp7gkSQL语句
select *
from (select d.*, rownum as num
from (SELECT A.BILLNO,
A.BILLCODE,
A.GETDATE,
A.GETUNITCODE,
A.GETCODE,
A.GETORGANCODE,
A.USEORGANCODE,
A.USEDATE,
A.USEUNITCODE,
A.USERCODE,
A.CURRENCYCODE,
A.AMOUNT,
A.NAME,
A.NOTES,
A.STATUSCODE,
A.IFPAGEONHOLE,
A.OPCODE,
A.OPUNITCODE,
A.OPDATE,
A.LOCKTIME,
A.GETAGENTCODE,
(SELECT D.AGENTNAME
FROM SYN_MM_AGENTCODE_TC D
WHERE D.AGENTCODE = A.GETAGENTCODE) AS GETAGENTNAME,
A.USEAGENTCODE,
A.OUTSTATUS,
CASE A.BILLCODE
WHEN 'B2010005' THEN
A.FACTBILLCODE
ELSE
''
END FACTBILLCODE,
A.SALES,
A.FROMDATE,
A.TODATE,
(SELECT BILLNAME
FROM BD_BILLCODE
WHERE BILLCODE = A.BILLCODE) BILLNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.USERCODE) USERNAME,
(SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.GETCODE) GETERNAME,
(SELECT NO3
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICENO,
(SELECT NO4
FROM B_BILLDETAIL
WHERE BILLNO = A.BILLNO
AND BILLCODE = A.BILLCODE
AND FACTBILLCODE = A.FACTBILLCODE) ONLINEINVOICECODE
FROM B_BILL A
WHERE 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND TRIM(BILLNO) >= :B1
AND TRIM(BILLNO) <= :B2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
ORDER BY A.BILLNO) d
where rownum <= 1)
where num > 0
执行计划:
Plan hash value: 4085294641
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4632 | 9 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL | CHAGENTBASE | 1 | 56 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS BY INDEX ROWID | BD_BILLCODE | 1 | 31 | 1 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | PK_BD_BILLCODE | 1 | | 0 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 6 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID | B_BILLDETAIL | 1 | 50 | 4 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 3 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID | B_BILLDETAIL | 1 | 50 | 4 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 3 (0)| 00:00:01 |
|* 12 | VIEW | | 1 | 4632 | 9 (0)| 00:00:01 |
|* 13 | COUNT STOPKEY | | | | | |
| 14 | VIEW | | 2 | 9238 | 9 (0)| 00:00:01 |
| 15 | TABLE ACCESS BY INDEX ROWID| B_BILL | 17395 | 3822K| 9 (0)| 00:00:01 |
|* 16 | INDEX FULL SCAN | PK_B_BILL_01 | 2 | | 8 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("D"."AGENTCODE"=:B1)
3 - access("BILLCODE"=:B1)
5 - access("A"."CODE"=:B1)
7 - access("A"."CODE"=:B1)
9 - access("BILLNO"=:B1 AND "BILLCODE"=:B2 AND "FACTBILLCODE"=:B3)
11 - access("BILLNO"=:B1 AND "BILLCODE"=:B2 AND "FACTBILLCODE"=:B3)
12 - filter("NUM">0)
13 - filter(ROWNUM<=1)
16 - filter(TO_NUMBER(TRIM("BILLNO"))>=601710100010 AND
TO_NUMBER(TRIM("BILLNO"))<=601710100010)
5). 对sql语句进行分析
1、SQL语句中有很多标量子查询,我们可以利用left join 对其改写。
2、id = 1 为TABLE ACCESS FULL,表示CHAGENTBASE走的是全表扫描,在标量子查询中,主表返回多少
行,子表也跟着被扫描多少次,所以需要对CHAGENTBASE建索引。
3、SQL语句中出现TRIM(BILLNO) >= :B1 AND TRIM(BILLNO) <= :B2,导致ID = 16 为
INDEX FULL SCAN。对主键进行索引全扫描,这种访问方式是最垃圾的。
优化
1)创建索引
create indexIDX_CHAGENTBASE_TEST on CHAGENTBASE (AGENTCODE);
2)标量改成left join
select *
from (select G.*, rownum as num
from (SELECT A.BILLNO,
A.BILLCODE,
A.GETDATE,
A.GETUNITCODE,
A.GETCODE,
A.GETORGANCODE,
A.USEORGANCODE,
A.USEDATE,
A.USEUNITCODE,
A.USERCODE,
A.CURRENCYCODE,
A.AMOUNT,
A.NAME,
A.NOTES,
A.STATUSCODE,
A.IFPAGEONHOLE,
A.OPCODE,
A.OPUNITCODE,
A.OPDATE,
A.LOCKTIME,
A.GETAGENTCODE,
/* (SELECT D.AGENTNAME
FROM SYN_MM_AGENTCODE_TC D
WHERE D.AGENTCODE = A.GETAGENTCODE) AS GETAGENTNAME*/
D.AGENTNAME AS GETAGENTNAME,
A.USEAGENTCODE,
A.OUTSTATUS,
CASE A.BILLCODE
WHEN 'B2010005' THEN
A.FACTBILLCODE
ELSE
''
END FACTBILLCODE,
A.SALES,
A.FROMDATE,
A.TODATE,
/* (SELECT BILLNAME
FROM BD_BILLCODE
WHERE BILLCODE = A.BILLCODE) BILLNAME,*/
B.BILLNAME,
/* (SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.USERCODE) USERNAME,*/
C.HANDLERNAME USERNAME,
/* (SELECT HANDLERNAME
FROM BD_HANDLER
WHERE HANDLERCODE = A.GETCODE) GETERNAME,*/
E.HANDLERNAME GETERNAME,
F.no3 ONLINEINVOICENO,
F.no4 ONLINEINVOICECODE
FROM B_BILL A
LEFT JOIN SYN_MM_AGENTCODE_TC D
ON D.AGENTCODE = A.GETAGENTCODE
LEFT JOIN BD_BILLCODE B
ON B.BILLCODE = A.BILLCODE
LEFT JOIN BD_HANDLER C
ON C.HANDLERCODE = A.USERCODE
LEFT JOIN BD_HANDLER E
ON E.HANDLERCODE = A.GETCODE
LEFT JOIN B_BILLDETAIL F
ON F.BILLNO = A.BILLNO
AND F.BILLCODE = A.BILLCODE
AND F.FACTBILLCODE = A.FACTBILLCODE
WHERE 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND trim(A.BILLNO) >= '601710100010'
AND trim(A.BILLNO) <= '601710100010'
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
AND 3 > 2
ORDER BY A.BILLNO)G
where rownum <= 1)
where num > 0;
Plan hash value: 1528527901
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4632 | 21 (0)| 00:00:01 |
|* 1 | VIEW | | 1 | 4632 | 21 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 2 | 9238 | 21 (0)| 00:00:01 |
| 4 | NESTED LOOPS OUTER | | 2 | 832 | 21 (0)| 00:00:01 |
| 5 | NESTED LOOPS OUTER | | 2 | 770 | 19 (0)| 00:00:01 |
| 6 | NESTED LOOPS OUTER | | 2 | 718 | 17 (0)| 00:00:01 |
| 7 | NESTED LOOPS OUTER | | 2 | 614 | 12 (0)| 00:00:01 |
| 8 | NESTED LOOPS OUTER | | 2 | 562 | 10 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID| B_BILL | 17395 | 3822K| 9 (0)| 00:00:01 |
|* 10 | INDEX FULL SCAN | PK_B_BILL_01 | 2 | | 8 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| CHAGENTBASE | 1 | 56 | 1 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | IDX_CHAGENTBASE_TEST | 1 | | 0 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 14 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 15 | TABLE ACCESS BY INDEX ROWID | B_BILLDETAIL | 1 | 52 | 3 (0)| 00:00:01 |
|* 16 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 2 (0)| 00:00:01 |
| 17 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 18 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 19 | TABLE ACCESS BY INDEX ROWID | BD_BILLCODE | 1 | 31 | 1 (0)| 00:00:01 |
|* 20 | INDEX UNIQUE SCAN | PK_BD_BILLCODE | 1 | | 0 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("NUM">0)
2 - filter(ROWNUM<=1)
10 - filter(TRIM("A"."BILLNO")>='601710100010' AND TRIM("A"."BILLNO")<='601710100010')
12 - access("D"."AGENTCODE"(+)="A"."GETAGENTCODE")
14 - access("A"."CODE"(+)="A"."GETCODE")
16 - access("F"."BILLNO"(+)="A"."BILLNO" AND "F"."BILLCODE"(+)="A"."BILLCODE" AND
"F"."FACTBILLCODE"(+)="A"."FACTBILLCODE")
18 - access("A"."CODE"(+)="A"."USERCODE")
20 - access("B"."BILLCODE"(+)="A"."BILLCODE")
3) 把Trim去掉
Execution Plan
----------------------------------------------------------
Plan hash value: 1229065410
------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 4632 | 13 (0)| 00:00:01 |
|* 1 | VIEW | | 1 | 4632 | 13 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | VIEW | | 1 | 4619 | 13 (0)| 00:00:01 |
| 4 | NESTED LOOPS OUTER | | 1 | 416 | 13 (0)| 00:00:01 |
| 5 | NESTED LOOPS OUTER | | 1 | 390 | 11 (0)| 00:00:01 |
| 6 | NESTED LOOPS OUTER | | 1 | 364 | 9 (0)| 00:00:01 |
| 7 | NESTED LOOPS OUTER | | 1 | 308 | 8 (0)| 00:00:01 |
| 8 | NESTED LOOPS OUTER | | 1 | 277 | 7 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID| B_BILL | 1 | 225 | 4 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | PK_B_BILL | 1 | | 3 (0)| 00:00:01 |
| 11 | TABLE ACCESS BY INDEX ROWID| B_BILLDETAIL | 1 | 52 | 3 (0)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | PK_B_BILLDETAIL_02 | 1 | | 2 (0)| 00:00:01 |
| 13 | TABLE ACCESS BY INDEX ROWID | BD_BILLCODE | 1 | 31 | 1 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | PK_BD_BILLCODE | 1 | | 0 (0)| 00:00:01 |
| 15 | TABLE ACCESS BY INDEX ROWID | CHAGENTBASE | 1 | 56 | 1 (0)| 00:00:01 |
|* 16 | INDEX RANGE SCAN | IDX_CHAGENTBASE_TEST | 1 | | 0 (0)| 00:00:01 |
| 17 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 18 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
| 19 | TABLE ACCESS BY INDEX ROWID | T_EMPLOYEE_VIEW | 1 | 26 | 2 (0)| 00:00:01 |
|* 20 | INDEX RANGE SCAN | IND_T_EMPLOYEE_VIEW | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("NUM">0)
2 - filter(ROWNUM<=1)
10 - access("A"."BILLNO"='601710100010')
12 - access("F"."BILLNO"(+)='601710100010' AND "F"."BILLCODE"(+)="A"."BILLCODE" AND
"F"."FACTBILLCODE"(+)="A"."FACTBILLCODE")
filter("F"."BILLNO"(+)="A"."BILLNO")
14 - access("B"."BILLCODE"(+)="A"."BILLCODE")
16 - access("D"."AGENTCODE"(+)="A"."GETAGENTCODE")
18 - access("A"."CODE"(+)="A"."GETCODE")
20 - access("A"."CODE"(+)="A"."USERCODE")
Statistics
----------------------------------------------------------
621 recursive calls
0 db block gets
229 consistent gets
17 physical reads
0 redo size
2937 bytes sent via SQL*Net to client
2086 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
16 sorts (memory)
0 sorts (disk)
1 rows processed
优化效果
可以看出消耗的 buffer cache 从之前的
882,856,212.00降到了229,效率提升了N倍.
又是latch: cache buffers chains惹得祸的更多相关文章
- 【转载】latch: cache buffers chains
本文转自惜分飞的博客,博客原文地址:www.xifenfei.com/1109.html,支持原创,分享知识! 当一个数据块读入sga区,相应的buffer header会被放置到hash列表上,我们 ...
- Oracle索引失效问题:WHERE C1='' OR C2 IN(SubQuery),并发请求时出现大量latch: cache buffers chains等待
问题描述: 项目反馈某功能响应时间很长,高峰期时系统整体响应很慢... 获取相应的AWR,问题确实比较严重,latch: cache buffers chains等待,因为这些会话SQL执行时间太长, ...
- latch: cache buffers chains故障处理总结(转载)
一大早就接到开发商的电话,说数据库的CPU使用率为100%,应用相应迟缓.急匆匆的赶到现场发现进行了基本的检查后发现是latch: cache buffers chains 作祟,处理过程还算顺利,当 ...
- 案例:latch: cache buffers chains event tuning
前两天对oracle数据库(single instance)进行了迁移升级从10.2.0.4 升到11.2.0.3,有一个项目迁完后第二天,cpu负载升到了130更高(16cpus). 向用户询问后使 ...
- latch: cache buffers chains故障处理总结
一大早就接到开发商的电话,说数据库的CPU使用率为100%,应用相应迟缓.急匆匆的赶到现场发现进行了基本的检查后发现是latch: cache buffers chains 作祟,处理过程还算顺利,当 ...
- 关于latch: cache buffers chains的sql优化
前段时间,优化了一些耗buffer比较多的sql,但是CPU使用率还是没下来 . 查看操作系统CPU使用率 查看awr,发现又有一条超级耗性能的sql冒出来了. 该SQL每次执行耗费3e多个buffe ...
- [转帖]深入理解latch: cache buffers chains
深入理解latch: cache buffers chains http://blog.itpub.net/12679300/viewspace-1244578/ 原创 Oracle 作者:wzq60 ...
- latch:cache buffers chains的优化思路
数据块在buffer cache存放是以linked list方式存放的.当一个session想要访问/修改buffer cache的block,首先需要通过hash算法检查该block是否存在于bu ...
- cache buffers chains latch
cache buffers chains latch 从 Oracle 8i Database 开始, 散列锁存器<-------(1:m)------>hash bucket<-- ...
随机推荐
- ubuntu 12.04 samba 配置(转载)
转自:http://blog.sina.com.cn/s/blog_a5b607f801013av9.html 首先当然是要安装samba了,呵呵: 代码: sudo apt-get install ...
- Ubuntu10.04安装与配置nfs服务器(转载)
转自:http://blog.chinaunix.net/uid-25885064-id-3177969.html 1.安装nfs服务 $ sudo apt-get install nfs-ker ...
- E20180206-E
fundamental adj. 基础的,基本的,根本的,重要的,原始的,主要的,十分重大的; [物] 基频的,基谐波的; [乐] 基音的; n. 原理,原则,基本,根本,基础; [乐] 基音; ...
- E20180128-hm
paradigm n. 范例,样式,模范; 词形变化表; outlet n. 出口,出路; 批发商店; 排水口,通风口; 发泄(情感)的方法;
- 关于PHP的框架
使用PHP框架有优点也有缺点,优点是避免重复劳动.简化很多操作.方便团队项目开发及维护,框架已经帮助你完成了很多工作,业务层主要侧重于业务功能的开发,缺点是由于调用框架对系统性能会有一点影响,因为框架 ...
- bzoj 4784: [Zjoi2017]仙人掌【tarjan+树形dp】
其实挺简单的但是没想出来---- 首先判断无解情况,即,一开始的图就不是仙人掌,使用tarjan判断如果一个点dfs下去有超过一个点比他早,则说明存在非简单环. 然后考虑dp,显然原图中已经属于某个简 ...
- [Swift]库函数atoi:将字符串内容转换为整数
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- Android项目通过Android Debug Database实时查看本地Sqlite数据库内容
前几天写Android项目时,想和Sqlyog那样图形化查看数据库中的文件,由于Android自带小型的Sqlite轻量级数据库,在查找方法时发现了一个特别简单适用的方法,纪录一下. 在android ...
- UTF-8格式的文本文件程序读取异常
最近在windows服务器上直接创建并手打输入配置参数,比如设置概率0.6,然后用java程序打开读取该参数,在本地linux环境下测试完全正常,但是一放到服务器上,就报NotNumber错误,查看了 ...
- Python——nose实例示例
1. 脚本示例: 执行结果: 2. 脚本示例: 执行结果: 由以上截图可以看出执行顺序: 大体可以得出如下结论: 1)测试的顺序总体上按照包—>模块—>类的顺序进行: 2) 然后按照测试用 ...