oracle性能優化之awr分析

oracle性能優化之awr分析html

做者:bingjavajava

 

最近某證券公司系統在業務期間系統運行緩慢,初步排查懷疑是數據庫存在性能問題,所以導出了oracle的awr報告進行分析,在此進行記錄。sql

致使系統的性能問題有不少,好比內存、cpu佔用率太高,網絡延遲、系統存儲io瓶頸、還有程序方面的代碼邏輯、性能低下的sql語句等等,這裏主要從awr的角度說明如何經過awr的報告來定位問題。數據庫

1、awr報告分析及問題定位

DB Name 性能優化

DB Id 服務器

Instance 網絡

Inst num session

Release 數據結構

RAC 併發

Host 

**DB

1527139216 

**DB

10.2.0.5.0

NO 

p3-**DB

 

Snap Id 

Snap Time 

Sessions 

Cursors/Session 

Begin Snap: 

16021 

01-Mar-16 10:00:34 

213 

2.4 

End Snap: 

16022 

01-Mar-16 11:00:36 

213 

2.3 

Elapsed: 

  

60.04 (mins) 

  

  

DB Time: 

  

176.32 (mins) 

  

  

關鍵項說明:

DB TIME:表明了此統計期間的數據庫負載,是全部前臺session花費在database調用上的總和時間(包括CPU時間、IO Time、和其餘一系列非空閒等待時間)。若是 DB Time 接近於 Elapsed Time*cpu 數,代表數據庫比較忙,cpu 負載也許比較大。這時頗有多是由於資源爭用致使等待事件的結果,能夠去 top 5 等待事件分析緣由。

Operating System Statistics

Statistic 

Total 

BUSY_TIME 

1,037,128 

IDLE_TIME 

10,487,927 

IOWAIT_TIME 

19,061

NICE_TIME 

316 

SYS_TIME 

132,552 

USER_TIME 

882,792 

LOAD 

RSRC_MGR_CPU_WAIT_TIME 

VM_IN_BYTES 

1,274,466,304 

VM_OUT_BYTES 

2,174,697,472 

PHYSICAL_MEMORY_BYTES 

33,712,308,224 

NUM_CPUS 

32 

NUM_CPU_SOCKETS 

 

 

從以上信息可知:

單數據庫實例,非集羣部署模式;2個物理cpu(NUM_CPU_SOCKETS=2),32個邏輯cpu(NUM_CPUS=32)。

cpu利用率爲:DB Time /(Elapsed* NUM_CPUS)=176/(60*32) *100%=9.2%

cpu的負載處於正常水平。

Load Profile

 

Per Second 

Per Transaction 

Redo size: 

89,367.47 

21,227.40 

Logical reads: 

105,600.68 

25,083.26 

Block changes: 

458.93 

109.01 

Physical reads:

27,716.84 

6,583.56 

Physical writes: 

30.80 

7.32 

User calls: 

3,675.70 

873.09 

Parses: 

324.60 

77.10 

Hard parses: 

14.13 

3.36 

Sorts: 

44.47 

10.56 

Logons: 

1.69 

0.40 

Executes: 

340.07 

80.78 

Transactions: 

4.21 

  

 

% Blocks changed per Read: 

0.43 

Recursive Call %:

16.91 

Rollback per transaction %: 

0.09 

Rows per Sort: 

397.30 

 

Redosize:每秒產生的日誌大小(單位字節),可標誌數據變動頻率,大的redosize每每對lgwr寫日誌,和arch歸檔形成I/O壓力,也有可能形成logbuffer堵塞從而產生相關的等待事件。很繁忙的系統中日誌生成量可能達到幾百k,甚至幾M。在Top 5 Timed Events中未發現log方面的等待事件,說明redo生成的頻率屬於正常範圍。

 

Logical reads: 從內存中讀取數據的次數(次數*塊數),每秒鐘邏輯讀數據量:105,600.68*8k=825m

Physical reads:當從內存中未都到數據時則從硬盤上讀取數據,每秒物理讀數據量:27,716.84 *8k=216m

Physical reads / Logical reads=27,716.84/105,600.68=26%,有26%的邏輯讀致使了物理io。所以此處的物理io多是系統的性能瓶頸(具體需在後面的 top 5中進行分析)。

Instance Efficiency Percentages (Target 100%)

Buffer Nowait %: 

98.73 

Redo NoWait %: 

100.00 

Buffer Hit %:

73.77 

In-memory Sort %: 

100.00 

Library Hit %: 

89.85 

Soft Parse %: 

95.65 

Execute to Parse %: 

4.55 

Latch Hit %: 

96.92 

Parse CPU to Parse Elapsd %: 

95.60 

% Non-Parse CPU: 

96.41 

 

buffer hit:表示進程從內存中找到數據塊的比率,監視這個值是否發生重大變化比這個 值自己更重要。對於通常的 OLTP 系統,一般應在 95%以上。不然應考慮加大 db_cache_size, 可是大量的非選擇的索引也會形成該值很高(大量的 db file sequential read)。

Latch Hit:Latch是一種保護內存結構的鎖,能夠認爲是SERVER進程獲取訪問內存數據結構的許可。要確保Latch Hit>99%,不然意味着Shared Pool latch爭用,可能因爲未共享的SQL,或者Library Cache過小,可以使用綁定變動或調大Shared Pool解決。

Execute to Parse:是語句執行與分析的比例,若是要SQL重用率高,則這個比例會很高。該值越高表示一次解析後被重複執行的次數越多。

 

Parse CPU to Parse Elapsd:該指標反映了快照內解析CPU時間和總的解析時間的比值(Parse CPU Time/ Parse Elapsed Time); 若該指標水平很低,那麼說明在整個解析過程當中 實際在CPU上運算的時間很短,而主要的解析時間都耗費在各類其餘非空閒的等待事件上了,此值越高越好。

 

Shared Pool Statistics

 

Begin 

End 

Memory Usage %:

56.42 

55.58 

% SQL with executions>1: 

54.12 

49.23 

% Memory for SQL w/exec>1: 

49.88 

48.29 

SQL with executions

:表明了sql重複執行的比例,本報告中是54%,是比較低的,說明存在sql硬編碼的狀況,同時上面的Execute to Parse也只有4.55%,也說明了sql解析的重用率低。

內存利用率爲55%左右,屬於正常狀況。

 

Top 5 Timed Events

業務11:00-12:00期間:

Event 

Waits 

Time(s) 

Avg Wait(ms) 

% Total Call Time 

Wait Class 

CPU time 

  

10,028 

  

94.8 

  

db file scattered read 

6,943,920 

644 

6.1 

User I/O 

read by other session 

4,837,558 

578 

5.5 

User I/O 

CSS initialization 

13 

65 

4,967 

.6 

Other 

db file sequential read

512,027 

58 

.6 

User I/O 

業務15:00-16:00期間

Event 

Waits 

Time(s) 

Avg Wait(ms) 

% Total Call Time 

Wait Class 

CPU time 

  

2,569 

  

95.8 

  

SQL*Net more data to client 

1,150,806 

233 

8.7 

Network 

db file scattered read 

1,381,500 

136 

5.1 

User I/O 

CSS initialization

13 

63 

4,878 

2.4 

Other 

db file sequential read 

42,488 

30 

1.1 

User I/O 

 

db file scattered read:

代表Oracle內核請求從磁盤讀取多個數據塊到buffer cache中,

這種狀況一般顯示與全表掃描相關的等待。當數據庫進行全表掃時,基於性能的考慮, 數據會分散讀入Buffer Cache。若是這個等待事件比較顯著,可能說明對於某些全表掃描的表,沒有建立索引或者沒有建立合適的索引。

read by other session:

Oracle 操做的最小單位是塊(Block),當對數據塊作修改時,其餘的會話將被阻止對這個數據塊上的數據作修改,可是能夠以一致性的方式讀取這個數據塊(from undo)。當前的用戶修改完這個數據塊後,將會當即釋放掉加在這個數據塊上的排他鎖,這樣另外一個會話就能夠繼續修改它,這種加鎖的機制叫Latch。當一個會話將數據塊都到內存中時,其它的會話同時也請求了這個數據塊,就致使被等待的會話出現read by other session。而當前會話通常是db file scattered read或db file sequential read。

從本次awr報告中都發現,db file scattered read、db file sequential read、read by other session這幾個事件的等待次數很高,所以能夠判斷當前業務場景存在熱點塊競爭問題。

 

SQL*Net more data to client:

    當服務器端有太多的數據須要發給客戶端時,可能會產生此等待事件,也可能因爲網絡問題致使服務器沒法及時地將信息或者處理結果發送給客戶端, 一樣會產生這個等待。在15:00--16:00業務期間此等待事件相對較高,從SQL*Net看並不像應用程序(應用程序是JDBC Thin Client),多是第三方的oracle監控程序致使的。

 

 

 

File IO Stats

Tablespace 

Filename 

Reads 

Av Reads/s 

Av Rd(ms) 

Av Blks/Rd 

Writes 

Av Writes/s 

Buffer Waits 

Av Buf Wt(ms) 

JSZ35_TBS 

*tbs01.dbf

2,635,786 

732 

0.10 

14.88 

4,032 

2,016,907 

0.12 

JSZ35_TBS 

*tbs02.dbf

2,730,384 

758 

0.09 

12.89 

10,420 

1,679,836 

0.12 

JSZ35_TBS 

*tbs03.dbf

2,084,937 

579 

0.08 

12.19 

9,183 

1,141,265 

0.13 

以上數據文件,平均每秒被讀700屢次,平均每秒讀取的數據塊爲14塊左右。

Tablespace IO Stats

Tablespace 

Reads 

Av Reads/s

Av Rd(ms) 

Av Blks/Rd 

Writes 

Av Writes/s 

Buffer Waits 

Av Buf Wt(ms) 

JSZ35_TBS 

1,420,317 

394 

0.11 

14.73 

9,502 

113 

2.30 

 

Segments by Buffer Busy Waits

Owner 

Tablespace Name 

Object Name 

Subobject Name 

Obj. Type 

Buffer Busy Waits 

% of Capture 

JSZ35 

JSZ35_TBS

TF_SUBJECTPRICE_TMP 

  

TABLE 

30 

32.26 

JSZ35 

JSZ35_TBS 

IND_T_*LOG

  

INDEX 

21 

22.58 

JSZ35 

JSZ35_TBS 

PK_T_**_TMP

  

INDEX 

15 

16.13 

JSZ35 

JSZ35_TBS 

T_***HER

CHER_P2016 

TABLE PARTITION 

9.68 

JSZ35 

JSZ35_TBS 

IND_T_***HER

  

INDEX 

 

其它業務時間段:

Owner 

Tablespace Name 

Object Name 

Subobject Name 

Obj. Type 

Buffer Busy Waits 

% of Capture 

JSZ35 

JSZ35_TBS 

IND_T_*LOG

  

INDEX 

60 

68.18 

JSZ35 

JSZ35_TBS 

IND_T_***SED

  

INDEX 

20 

22.73 

 

JSZ35 

JSZ35_TBS 

TF_SUBJECTPRICE_TMP 

 

TABLE 

18 

17.65 

JSZ35 

JSZ35_TBS

IND_T_***HER

 

INDEX 

6.86 

 

Segments by Physical Reads

Owner 

Tablespace Name 

Object Name 

Subobject Name 

Obj. Type 

Physical Reads 

%Total 

JSZ35 

JSZ35_TBS 

T_***NCE

ANCE_P2015 

TABLE PARTITION 

81,573,441 

81.70 

JSZ35 

JSZ35_TBS 

T_***NCE

ANCE_P2016 

TABLE PARTITION

12,884,029 

12.90 

JSZ35 

JSZ35_TBS 

T_***CE

RICE_P2016 

TABLE PARTITION 

3,471,341 

3.48 

熱點數據塊主要是T_***NCE、T_***CE引發。

數據塊熱點問題io等待的主要對象爲:

T_***LOG、TF_SUBJECTPRICE_TMP、TS_PROCESSED、TF_SUBJECTPRICE_TMP、T_***NCE、T_***CE

可結合SQL ordered by CPU Time(最耗時的sql)、SQL ordered by Gets(邏輯讀最多的sql)、SQL ordered by Reads(物理讀最多的sql)來定位具體的sql語句。

 

2、問題總結及解決方式

    本報告期,系統的cpu、內存表現正常,形成系統性能問題的主要緣由爲物理讀過多,產生io等待;同時因爲相關業務表存在頻繁的併發訪問現象(邏輯讀較多)且性能較差而致使了數據塊競爭問題。邏輯讀是消耗cpu的,而物理讀是消耗io的,這也說明了系統的大部分時間都消耗在io等待上,因此cpu相對空閒。

優化方案主要包括應用層的優化和oracle數據庫的優化:

    1、應用層的優化目標主要在於下降對數據庫的訪問頻率、合理有效使用索引(合理有效使用索引,需經過對sql語句的執行計劃進行分析和調優):

  1. T_***LOG可能存在較頻繁的插入數據操做,可採用如下方式減小對數據庫的提交操做:

將此表的單條insert的操做改成批量入庫提交的方式(比例100條記錄入庫一次)。

  1. T_***_TMP可能存在讀寫混合的場景,需根據業務分析是否有優化的空間。
  1. T_***NCE、T_***CE、T_A***T,關於此表的相關訪問應該是最須要優化的了,需優化的sql語句爲(好比索引是否合理):

關鍵sql語句:SELECT /*+ LEADING ("A3" "A2" "A1") PQ_DISTRIBUTE ("A1", BROADCAST, NONE)USE_NL ("A1") FULL ("A1") PQ_DISTRIBUTE ("A2", BROADCAST, NONE)USE_NL ("A2") FULL ("A2") FULL ("A3") */ "A3"."FSETCODE", "A2"."FDATE", "A1"."FSETNAME", SUM(CASE WHEN "A3"."FACCTATTR" LIKE '??±????%' THEN "A2"."FENDBAL" ELSE 0 END ), SUM(CASE WHEN "A3"."FACCTATTR" LIKE '???±£??%' THEN "A2"."FENDBAL" ELSE 0 END ) FROM "T_A***T" "A3", "T_***NCE" "A2", "T_AS**T" "A1" WHERE "A3"."FACCTDETAIL"=1 AND "A2"."FDATE"=TO_DATE(TO_CHAR(:1), 'yyyy-mm-dd') AND ("A3"."FACCTATTR" LIKE '??±????%' OR "A3"."FACCTATTR" LIKE '???±£??') AND "A3"."FSETCODE"="A1"."FSETCODE" AND "A3"."FSETCODE"="A2"."FSETCODE" AND "A3"."FACCTCODE"="A2"."FACCTCODE" GROUP BY "A3"."FSETCODE", "A2"."FDATE", "A1"."FSETNAME"

select sum(NVL(fbacccredit, 0)) as fje from(select fsetcode, facctcode, fbacccredit from T_***NCE where fsetcode=:1 and fdate=:2 ) a left join T_A***T b on a.fsetcode = b.fsetcode and a.facctcode = b.facctcode where b.facctattr like :3 and b.facctdetail=1

select a.fdate, a.fsetcode, a.fzqdm, a.fhqssj, a.fhqpjj, a.fbjsj, a.fsjsj, a.fzdcj, a.fjyzt, a.fjysc, a.fzqlb, a.fsyqx, a.fdatasource, a.fyqfyfx, a.fgzjgly, a.ftpdate from T_***CE a where fsh = 1 and fdate = to_date('2016-02-29', 'yyyy-MM-dd') and a.fsetcode = 0 union select a.fdate, a.fsetcode, a.fzqdm, a.fhqssj, a.fhqpjj, a.fbjsj, a.fsjsj, a.fzdcj, a.fjyzt, a.fjysc, a.fzqlb, a.fsyqx, a.fdatasource, a.fyqfyfx, a.fgzjgly, a.ftpdate from (select fdate, fsetcode, fzqdm, fhqssj, fhqpjj, fbjsj, fsjsj, fzdcj, fjyzt, fjysc, fzqlb, fsyqx, fdatasource, fyqfyfx, fgzjgly, ftpdate, fsh from T_***CE where fzqlb = 'JJ') a right join (select FDate, FZqdm, fjysc From T_***CE where fsh = 1 and fdate = to_date('2016-02-26', 'yyyy-MM-dd') and fsetcode = 0 and fzqlb = 'JJ') b on b.FDate = a.FDate and a.FZqdm = b.FZqdm and a.fjysc = b.fjysc and a.fsh = 1 where fsetcode = 0 and a.fjysc = 'Y'

關鍵的sql語句:其中上面的第一條語句執行狀況,SQL ordered by Elapsed Time:

Elapsed Time (s) 

CPU Time (s) 

Executions 

Elap per Exec (s) 

% Total DB Time

SQL Id 

SQL Module 

SQL Text 

3,519 

3,601 

  

33.26 

f089ggtmuxsnu

oracle@p3tgbmsdb1 (TNS V1-V3) 

SELECT /*+ LEADING… 

1,305 

1,086 

158 

8.26 

12.34 

7m0bfdfskwgcc

JDBC Thin Client 

select sum(…

該語句執行了3600秒(即整個快照期)都還未執行完成,該語句是三張表的關聯統計查詢,oracle自動對其進行並行查詢,可能因爲此三張表(T_A***T、T_***NCE、T_AS**T)的數據量較大,尤爲是T_A***T的數據量較大時更是影響性能,採用並行查詢後反而致使了對io的爭用,下降了性能。

四、全表掃描問題

大表在一小時內發生了822次全表掃描,若是表的數據比較大則對性能有很大影響。小表每秒中有28次全表掃描,需重點優化以上3條sql語句。

table scans (direct read)

0.00 

0.00 

table scans (long tables) 

822 

0.23 

0.07 

table scans (rowid ranges) 

0.00 

0.00 

table scans (short tables) 

102,749 

28.52 

8.27 

total number of times SMON posted 

22 

0.01 

 

 

 

2、oracle優化

      一、合理設置DB_FILE_MULTIBLOCK_READ_COUNT,此參數控制在多數據塊讀時一次讀入數據塊的次數。適當增長這個參數大小,可以提升多數據塊操做(如全表掃描)的IO效率。

二、能夠考慮對以上熱點表重建索引、分區表等方式來下降該數據段上的IO負荷,將歷史數據進行分離(好比根據業務狀況將2015年以前的數據轉移到另外的備份庫中)。

三、因Buffer Hit只有73%,可根據Buffer Pool Advisory調整buffer pool大小爲:16g。

四、將頻繁併發訪問的表或數據移到另外一數據塊或者進行更大範圍的分佈(能夠增大pctfree值 ,擴大數據分佈,減小競爭)。

五、屬於index block的表(如T_***SED、T_***_TMP),應該考慮重建索引、分割索引或使用反向鍵索引。關於反向鍵索引需根據sql語句查詢特色進行有選擇使用(若是在where中對索引列進行了範圍搜索,則會致使該索引無效會進行全表掃描,反向鍵索引只對<>\=有效)。    

*******************************************************************************
做者: bingjava
版權聲明:本文爲博主原創文章,轉載請說明出處: http://www.cnblogs.com/bingjava/ *******************************************************************************
相關文章
相關標籤/搜索