一个使用柱状图的案例[转]

客户的系统突然WIO超高:

09:02:23 %usr %sys %wio %idle
09:02:24 15 3 79 4
09:02:25 6 4 86 4
09:02:26 5 3 92 0
09:02:27 8 2 89 1
09:02:28 10 3 82 5
09:02:29 7 2 90 1
09:02:30 7 2 91 0
09:02:31 5 4 90 1
09:02:32 6 1 87 6

通过STATSPACK报告看到:

Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Buffer Nowait %: 98.84 Redo NoWait %: 100.00
Buffer Hit %: 20.33 In-memory Sort %: 100.00
Library Hit %: 94.41 Soft Parse %: 89.96
Execute to Parse %: 2.39 Latch Hit %: 99.53
Parse CPU to Parse Elapsd %: 95.73 % Non-Parse CPU: 98.75

Top 5 Timed Events
~~~~~~~~~~~~~~~~~~ % Total
Event Waits Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
db file sequential read 153,738 920 67.67
CPU time 377 27.73
buffer busy waits 4,820 26 1.91
db file parallel write 1,776 12 .86
SQL*Net message from dblink 23,712 9 .67
-------------------------------------------------------------

DB CACHE的命中率只有20%,经过检查发现有几个TOP SQL:

SQL ordered by Reads for DB: PCS Instance: pcs Snaps: 654 -655
-> End Disk Reads Threshold: 1000

CPU Elapsd
Physical Reads Executions Reads per Exec %Total Time (s) Time (s) Hash Value
--------------- ------------ -------------- ------ -------- --------- ----------
369,695 14 26,406.8 21.6 26.49 143.65 1920692241
Module: 。。。 (TNS V1-V3)
select a.filename, b.source_id, b.source_path, b.localnet_
abbr from SCH_XXXXX a, source b where a.deal_flag='W' and
a.validflag='Y' and b.pipe_id=:szPipeId and a.source_id=b.sourc
e_id

类似的SQL有几个,看样子必须解决这几个SQL才能解决这个问题。看了看执行计划
--------------------------------------------------------------------------------
| Operation                      | PHV/Object Name     |  Rows | Bytes|   Cost |
--------------------------------------------------------------------------------
|SELECT STATEMENT                |----- 1104374539 ----|       |      |   3486 |
|HASH JOIN                       |                     |    79K|    7M|   3486 |
| TABLE ACCESS BY INDEX ROWID    |SOURCE               |     2 |   98 |      2 |
|  INDEX RANGE SCAN              |FK_SOURCE_WORKFLOW   |     1 |      |      1 |
| TABLE ACCESS FULL              |SCH_XXXXX            |     1M|   61M|   3474 |
--------------------------------------------------------------------------------
SCH_XXXXX表有250万条记录。做全表扫描是不合适的。

分析WHERE条件发现,在该表上有过滤器:

a.deal_flag='W' and a.validflag='Y'

deal_flag和validflag都是状态字段,取值范围都很小,只有2、3个值。客户以前也创建过索引,不过优化器无法选择索引,因此就把索引去掉了。

通过检查发现validflag的取值绝大多数都是'Y',而deal_flag是一个倾斜的列,绝大多数记录是'Y',只有少量记录是'W',并且这个SQL在WHERE条件的A.DEAL_FLAG上没有使用绑定变量,因此可以在deal_flag上创建一个索引,并且通过分析柱状图来解决这个问题。

CREATE INDEX IDX_XXX_DEALFLAG ON SHCJ.SCH_XXXXX(DEAL_FLAG) ;

exec DBMS_STATS.GATHER_TABLE_STATS(ownname=>'SHCJ', tabname=>'SCH_XXXXX', estimate_percent=>30, -
method_opt=>'for all indexed columns size skewonly',cascade=>true, degree=>4);

通过上述操作后:

Instance Efficiency Percentages (Target 100%)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Buffer Nowait %: 100.00 Redo NoWait %: 100.00
Buffer Hit %: 99.99 In-memory Sort %: 100.00
Library Hit %: 94.03 Soft Parse %: 89.37
Execute to Parse %: 2.39 Latch Hit %: 100.00
Parse CPU to Parse Elapsd %: 94.51 % Non-Parse CPU: 96.88

使用sar -d命令:

11:46:13 %usr %sys %wio %idle
11:46:14 0 0 1 99
11:46:15 6 1 2 91
11:46:16 4 0 0 96
11:46:17 1 2 2 95
11:46:18 1 0 1 98
11:46:19 15 0 12 73
11:46:20 6 1 22 71
11:46:21 1 0 5 94
11:46:22 9 0 1 90
11:46:23 1 0 0 99

Average 4 0 5 91



故障解决。这个案例可以学到以下的知识:

1、对于取值较少的字段,如果是倾斜的,而我们的查询结果是数据量较小的,这种情况,在这个字段上创建B树索引,是可以起作用的

2、索引起作用的前提是必须对该字段采集柱状图信息,并且SQL中该字段的条件不能使用绑定变量(如果使用绑定变量由于BIND PEEKING,会导致执行计划不稳定)

posted on 2008-09-28 00:57  一江水  阅读(845)  评论(0编辑  收藏  举报