1. 程式人生 > 實用技巧 >循序漸進解讀Oracle AWR效能分析報告

循序漸進解讀Oracle AWR效能分析報告

循序漸進解讀Oracle AWR效能分析報告

2020 年 2 月 17 日

語言 & 開發新基建最佳實踐

作者介紹

韓鋒,宜信技術研發中心資料庫架構師。精通多種關係型資料庫,曾任職於噹噹網、TOM線上等公司,曾任多家公司首席DBA、資料庫架構師等職,多年一線資料庫架構、設計、開發經驗。著有《SQL優化最佳實踐》一書。

Oracle 中的 AWR,全稱為 Automatic Workload Repository,自動負載資訊庫。它收集關於特定資料庫的操作統計資訊和其他統計資訊,Oracle 以固定的時間間隔(預設為 1 個小時)為其所有重要的統計資訊和負載資訊執行一次快照,並將快照存放入 AWR 中。這些資訊在 AWR 中保留指定的時間(預設為 1 周),然後執行刪除。執行快照的頻率和保持時間都是可以自定義的。

AWR 的引入,為我們分析資料庫提供了非常好的便利條件(這方面 MySQL 就相差了太多)。曾經有這樣的一個比喻——“一個系統,就像是一個黑暗的大房間,系統收集的統計資訊,就如同放置在房間不同位置的蠟燭,用於照亮這個黑暗大房間。Oracle,恰到好處地放置了足夠的蠟燭(AWR),房間中只有極少的燭光未覆蓋之處,效能瓶頸就容易定位。而對於蠟燭較少或是沒有蠟燭的系統,效能優化就如同黑暗中的舞者。”

那如何解讀 AWR 的資料呢?Oracle 本身提供了一些報告,方便進行檢視、分析。下面就針對最為常見的一種報告——《AWR 資料庫報告》進行說明。希望通過這篇文章,能方便大家更好地利用 AWR,方便進行分析工作。

一、MAIN

Database Information

Snapshot Information

(1)Sessions

表示採集例項連線的會話數。這個數可以幫助我們瞭解資料庫的併發使用者數大概的情況。這個數值對於我們判斷資料庫的型別有幫助。

(2)Cursors/session

每個會話平均開啟的遊標數。

(3)Elapsed

通過 Elapsed/DB Time 比較,反映出資料庫的繁忙程度。如果 DB Time>>Elapsed,則說明資料庫很忙。

(4)DB Time

表示使用者操作花費的時間,包括 CPU 時間和等待事件。通常同時這個數值判讀資料庫的負載情況。

具體含義

db time = cpu time + wait time(不包含空閒等待)(非後臺程序)

*db time 就是記錄的伺服器花在資料庫運算(非後臺程序)和等待(非空閒等待)上的時間。對應於 V$SESSION 的 elapsed_time 欄位累積。

"合集資料"

需要注意的是 AWR 是一個數據合集。比如在 1 分鐘之內,1 個使用者等待了 30 秒鐘,那麼 10 個使用者等待事件就是 300 秒。CPU 時間也是一樣,在 1 分鐘之內,1 個 CPU 處理 30 秒鐘,那麼 4 個 CPU 就是 120 秒。這些時間都是以累積的方式記錄在 AWR 當中的。

示例

DB CPU——這是一個用於衡量 CPU 的使用率的重要指標。假設系統有 N 個 CPU,那麼如果 CPU 全忙的話,一秒鐘內的 DB CPU 就是 N 秒。除了利用 CPU 進行計算外,資料庫還會利用其它計算資源,如網路、硬碟、記憶體等等,這些對資源的利用同樣可以利用時間進行度量。假設系統有 M 個 session 在執行,同一時刻有的 session 可能在利用 CPU,有的 session 可能在訪問硬碟,那麼在一秒鐘內,所有 session 的時間加起來就可以表徵系統在這一秒內的繁忙程度。一般的,這個和的最大值應該為 M。這其實就是 Oracle 提供的另一個重要指標:DB time,它用以衡量前端程序所消耗的總時間。

對除 CPU 以後的計算資源的訪問,Oracle 用等待事件進行描述。同樣地,和 CPU 可分為前臺消耗 CPU 和後臺消耗 CPU 一樣,等待事件也可以分為前臺等待事件和後臺等待事件。DB Time 一般的應該等於"DB CPU + 前臺等待事件所消耗時間"的總和。等待時間通過 vsystemeventDBTimeDBCPUvsys_time_model 進行統計。

--"Load Profile"中關於 DB Time 的描述

*這個系統的 CPU 個數是 8,因此我們可以知道前臺程序用了系統 CPU 的 7.1/8=88.75%。DB Time/s 為 11.7,可以看出這個系統是 CPU 非常繁忙的。裡面 CPU 佔了 7.1,則其它前臺等待事件佔了 11.7 – 7.1 = 4.6 Wait Time/s。DB Time 佔 DB CPU 的比重: 7.1/11.7= 60.68%

--"Top 5 Timed Events"中關於 DB CPU 的描述

按照 CPU/等待事件佔 DB Time 的比例大小,這裡列出了 Top 5。如果一個工作負載是 CPU 繁忙型的話,那麼在這裡應該可以看到 DB CPU 的影子。

*注意到,我們剛剛已經算出了 DB CPU 的 %DB time,60%。其它的 external table read、direct path write、PX Deq: read credit、PX Deq: Slave Session Stats 這些就是佔比重 40 的等待事件裡的 Top 4 了。

--"Top 5 Timed Foreground Events"的侷限性

再研究下這個 Top 5 Timed Foreground Events,如果先不看 Load Profile,是不能計算出一個 CPU-Bound 的工作負載。要知道系統 CPU 的繁忙程式,還要知道這個 AWR 所基於兩個 snapshot 的時間間隔,還要知道系統 CPU 的個數。要不繫統可以是一個很 IDLE 的系統呢。記住 CPU 利用率 = DB CPU/(CPU_COUNT*Elapsed TIME)。這個 Top 5 給我們的資訊只是這個工作負載應該是並行查詢,從外部表讀取資料,並用 insert append 的方式寫入磁碟,同時,主要時間耗費在 CPU 的運算上。

** --解讀"DB Time" > “DB CPU” + “前臺等待事件所消耗時間” ——程序排隊時間 **

上面提到,DB Time 一般的應該等於 DB CPU + 前臺等待事件所消耗時間的總和。在下面有對這三個值的統計:

DB CPU = 6474.65

DB TIME = 10711.2

FG Wait Time = 1182.63

明顯的,DB CPU + FG Wait Time < DB Time,只佔了 71.5%

*其它的 28.5%被消耗到哪裡去了呢?這裡其實又隱含著一個 Oracle 如何計算 DB CPU 和 DB Time 的問題。當 CPU 很忙時,如果系統裡存在著很多程序,就會發生程序排隊等待 CPU 的現象。在這樣,DB TIME 是把程序排隊等待 CPU 的時間算在內的,而 DB CPU 是不包括這一部分時間。這是造成 DB CPU + FG Wait Time < DB Time 的一個重要原因。如果一個系統 CPU 不忙,這這兩者應該就比較接近了。不要忘了在這個例子中,這是一個 CPU 非常繁忙的系統,而 71.5%就是一個訊號,它提示著這個系統可能是一個 CPU-Bound 的系統。

二、Report Summary

1.Cache Sizes

2.Load Profile

這兩部分是資料庫資源負載的一個明細列表,分隔成每秒鐘的資源負載和每個事務的資源負載。

  • Redo size

每秒(每個事務)產生的日誌大小(單位位元組)

  • Logical reads

每秒(每個事務)產生的邏輯讀(單位是 block)。在很多系統裡 select 執行次數要遠遠大於 transaction 次數。這種情況下,可以參考 Logical reads/Executes。在良好的 oltp 環境下,這個應該不會超過 50,一般只有 10 左右。如果這個值很大,說明有些語句需要優化。

  • Block Changes

每秒(每個事務)改變的資料塊數。

  • Physical reads

每秒(每個事務)產生的物理讀(單位是 block)。一般物理讀都會伴隨邏輯讀,除非直接讀取這種方式,不經過 cache。

  • Physical writes

每秒(每個事務)產生的物理寫(單位是 block)。

  • User calls

每秒(每個事務)使用者呼叫次數。User calls/Executes 基本上代表了每個語句的請求次數,Executes 越接近 User calls 越好。

  • Parses

每秒(每個事務)產生的解析(或分析)的次數,包括軟解析和硬解析,但是不包括快速軟解析。軟解析每秒超過 300 次意味著你的"應用程式"效率不高,沒有使用 soft soft parse,調整 session_cursor_cache。

  • Hard parses

每秒(每個事務)產生的硬解析次數。每秒超過 100 次,就可能說明你繫結使用的不好。

  • Sorts

每秒(每個事務)排序次數。

  • Logons

每秒(每個事務)登入資料庫次數。

  • Executes

每秒(每個事務)SQL 語句執行次數。包括了使用者執行的 SQL 語句與系統執行的 SQL 語句,表示一個系統 SQL 語句的繁忙程度。

  • Transactions

每秒的事務數。表示一個系統的事務繁忙程度。目前已知的最繁忙的系統為淘寶的線上交易系統,這個值達到了 1000。

  • % Blocks changed per Read

表示邏輯讀用於只讀而不是修改的塊的比例。如果有很多 PLSQL,那麼就會比較高。

  • Rollback per transaction %

看回滾率是不是很高,因為回滾很耗資源。

  • Recursive Call %

遞迴呼叫 SQL 的比例,在 PL/SQL 上執行的 SQL 稱為遞迴的 SQL。

3.Instance Efficiency Percentages (Target 100%)

這個部分是記憶體效率的統計資訊。對於 OLTP 系統而言,這些值都應該儘可能地接近 100%。對於 OLAP 系統而言,意義不太大。因為在 OLAP 系統中,大查詢的速度才是對效能影響的最大因素。

  • Buffer Nowait %

非等待方式獲取資料塊的百分比。

這個值偏小,說明發生 SQL 訪問資料塊時資料塊正在被別的會話讀入記憶體,需要等待這個操作完成。發生這樣的事情通常就是某些資料塊變成了熱塊。

Buffer Nowait<99%說明,有可能是有熱塊(查詢 xbhtchvlatch_children 的 cache buffers chains)。

  • Redo NoWait %

非等待方式獲取 redo 資料百分比。

  • Buffer Hit %

資料緩衝命中率,表示了資料塊在資料緩衝區中的命中率。

Buffer Hit<95%,可能是要加 db_cache_size,但是大量的非選擇的索引也會造成該值很高(大量的 db file sequential read)。

  • In-memory Sort %

資料塊在記憶體中排序的百分比。總排序中包括記憶體排序和磁碟排序。當記憶體中排序空間不足時,使用臨時表空間進行排序,這個是記憶體排序對總排序的百分比。

過低說明有大量排序在臨時表空間進行。在 oltp 環境下,最好是 100%。如果太小,可以調整 PGA 引數。

  • Library Hit %

共享池中 SQL 解析的命中率。

Library Hit<95%,要考慮加大共享池,繫結變數,修改 cursor_sharing 等。

  • Soft Parse %

軟解析佔總解析數的百分比。可以近似當作 sql 在共享區的命中率。

這個數值偏低,說明系統中有些 SQL 沒有重用,最優可能的原因就是沒有使用繫結變數。

<95%:需要考慮到繫結

<80%:那麼就可能 sql 基本沒有被重用

  • Execute to Parse %

執行次數對分析次數的百分比。

如果該值偏小,說明解析(硬解析和軟解析)的比例過大,快速軟解析比例小。根據實際情況,可以適當調整引數 session_cursor_cache,以提高會話中 sql 執行的命中率。

round(100*(1-:prse/:exe),2) 即(Execute 次數 - Parse 次數)/Execute 次數 x 100%

prse = select value from v$sysstat where name = ‘parse count (total)’;

exe = select value from v$sysstat where name = ‘execute count’;

沒繫結的話導致不能重用也是一個原因,當然 sharedpool 太小也有可能,單純的加 session_cached_cursors 也不是根治的辦法,不同的 sql 還是不能重用,還要解析。即使是 soft parse 也會被統計入 parse count,所以這個指標並不能反應出 fast soft(pga 中)/soft (shared pool 中)/hard (shared pool 中新解析) 幾種解析的比例。只有在 pl/sql 的類似迴圈這種程式中使用使用變數才能避免大量 parse,所以這個指標跟是否使用 bind 並沒有必然聯絡增加 session_cached_cursors 是為了在大量 parse 的情況下把 soft 轉化為 fast soft 而節約資源。

  • Latch Hit %

latch 的命中率。

其值低是因為 shared_pool_size 過大或沒有使用繫結變數導致硬解析過多。要確保>99%,否則存在嚴重的效能問題,比如繫結等會影響該引數。

  • Parse CPU to Parse Elapsd %

解析總時間中消耗 CPU 的時間百分比。即:100*(parse time cpu / parse time elapsed)

解析實際執行事件/(解析實際執行時間+解析中等待資源時間),越高越好。

  • % Non-Parse CPU

CPU 非分析時間在整個 CPU 時間的百分比。

100*(parse time cpu / parse time elapsed)= Parse CPU to Parse Elapsd %

查詢實際執行時間/(查詢實際執行時間+sql 解析時間),太低表示解析消耗時間過多。

4.Shared Pool Statistics

  • Memory Usage %

共享池記憶體使用率。

應該穩定在 70%-90%間,太小浪費記憶體,太大則記憶體不足。

  • % SQL with executions>1

執行次數大於 1 的 SQL 比率。

若太小可能是沒有使用繫結變數。

  • % Memory for SQL w/exec>1

執行次數大於 1 的 SQL 消耗記憶體/所有 SQL 消耗的記憶體(即 memory for sql with execution > 1)。

5.Top 5 Timed Events

三、RAC Statistics

這一部分只在有 RAC 環境下才會出現,是一些全域性記憶體中資料傳送、接收方面的效能指標,還有一些全域性鎖的資訊。除非這個資料庫在執行正常是設定了一個基線作為參照,否則很難從這部分資料中直接看出效能問題。

經驗

Oracle 公司經驗,下面 GCS 和 GES 各項指標中,凡是與時間相關的指標,只要 GCS 指標低於 10ms,GES 指標低於 15ms,則一般表示節點間通訊效率正常。但是,即便時間指標正常,也不表示應用本身或應用在 RAC 部署中沒有問題。

1.Global Cache Load Profile

2.Global Cache Efficiency Percentages (Target local+remote 100%)

3.Global Cache and Enqueue Services - Workload Characteristics

4.Global Cache and Enqueue Services - Messaging Statistics

5.Global Cache Transfer Stats

*如果 CR 的 %Busy 很大,說明節點間存在大量的塊爭用。

四、Wait Events Statistics

1.Time Model Statistics

這部分資訊列出了各種操作佔用的資料庫時間比例。

  • parse time elapsed/hard parse elapsed time

通過這兩個指標的對比,可以看出硬解析佔整個的比例。如果很高,就說明存在大量硬解析。

  • % Not-Parse CPU

花費在非解析上 CPU 消耗佔整個 CPU 消耗的比例。反之,則可以看出解析佔用情況。如果很高,也可以反映出解析過多(進一步可以看看是否是硬解析過多)。

示例 - 計算 CPU 消耗

Total DB CPU = DB CPU + background cpu time = 1305.89 + 35.91 = 1341.8 seconds

再除以總的 BUSY_TIME + IDLE_TIME

% Total CPU = 1341.8/1941.76 = 69.1%,這剛好與上面 Report 的值相吻合。

其實,在 Load Profile 部分,我們也可以看出 DB 對系統 CPU 的資源利用情況。

用 DB CPU per Second 除以 CPU Count 就可以得到 DB 在前臺所消耗的 CPU%了。

這裡 5.3/8 = 66.25 %

比 69.1%稍小,說明 DB 在後臺也消耗了大約 3%的 CPU。

2.Wait Class

這一部分是等待的型別。可以看出那類等待佔用的時間最長。

3.Wait Events

這一部分是整個例項等待事件的明細,它包含了 TOP 5 等待事件的資訊。

%Time-outs: 超時百分比(超時依據不太清楚?)

4.Background Wait Events

這一部分是例項後臺程序的等待事件。如果我們懷疑那個後臺程序(比如 DBWR)無法及時響應,可以在這裡確認一下是否有後臺程序等待時間過長的事件存在。

5.Operating System Statistics

(1)背景知識

如果關注資料庫的效能,那麼當拿到一份 AWR 報告的時候,最想知道的第一件事情可能就是系統資源的利用情況了,而首當其衝的,就是 CPU。而細分起來,CPU 可能指的是:

  • OS級的User%, Sys%, Idle%

  • DB所佔OS CPU資源的Busy%

  • DB CPU又可以分為前臺所消耗的CPU和後臺所消耗的CPU

(2)11g

如果資料庫的版本是 11g,那麼很幸運的,這些資訊在 AWR 報告中一目瞭然:

OS 級的 %User 為 75.4,%Sys 為 2.8,%Idle 為 21.2,所以 %Busy 應該是 78.8。

DB 佔了 OS CPU 資源的 69.1,%Busy CPU 則可以通過上面的資料得到:%Busy CPU = %Total CPU/(%Busy) * 100 = 69.1/78.8 * 100 = 87.69,和報告的 87.7 相吻合。

(3)10g

如果是 10g,則需要手工對 Report 裡的一些資料進行計算了。Host CPU 的結果來源於 DBA_HIST_OSSTAT,AWR 報告裡已經幫忙整出了這段時間內的絕對資料(這裡的時間單位是釐秒-也就是 1/100 秒)。

解讀輸出

%User = USER_TIME/(BUSY_TIME+IDLE_TIME)*100 = 146355/(152946+41230)*100 = 75.37

%Sys = SYS_TIME/(BUSY_TIME+IDLE_TIME)*100

%Idle = IDLE_TIME/(BUSY_TIME+IDLE_TIME)*100

ELAPSED_TIME

這裡已經隱含著這個 AWR 報告所捕捉的兩個 snapshot 之間的時間長短了。有下面的公式。正確的理解這個公式可以對系統 CPU 資源的使用及其度量的方式有更深一步的理解。

BUSY_TIME + IDLE_TIME = ELAPSED_TIME * CPU_COUNT

推算出:ELAPSED_TIME = (152946+41230)/8/100 = 242.72 seconds //這是正確的。

時間統計檢視 v$sys_time_model

至於 DB 對 CPU 的利用情況,這就涉及到 10g 新引入的一個關於時間統計的檢視 - v$sys_time_model。簡單而言,Oracle 採用了一個統一的時間模型對一些重要的時間指標進行了記錄,具體而言,這些指標包括:

  1. background elapsed time

  2. background cpu time

  3. RMAN cpu time (backup/restore)

  4. DB time

  5. DB CPU

  6. connection management call elapsed time

  7. sequence load elapsed time

  8. sql execute elapsed time

  9. parse time elapsed

  10. hard parse elapsed time

  11. hard parse (sharing criteria) elapsed time

  12. hard parse (bind mismatch) elapsed time

  13. failed parse elapsed time

  14. failed parse (out of shared memory) elapsed time

  15. PL/SQL execution elapsed time

  16. inbound PL/SQL rpc elapsed time

  17. PL/SQL compilation elapsed time

  18. Java execution elapsed time

  19. repeated bind elapsed time

我們這裡關注的只有和 CPU 相關的兩個: background cpu time 和 DB CPU。這兩個值在 AWR 裡面也有記錄。

五、SQL Statistics

1.SQL ordered by Elapsed Time

這一部分是按照 SQL 執行時間從長到短的排序。

  • Elapsed Time(S)

SQL 語句執行用總時長,此排序就是按照這個欄位進行的。注意該時間不是單個 SQL 跑的時間,而是監控範圍內 SQL 執行次數的總和時間。單位時間為秒。Elapsed Time = CPU Time + Wait Time

  • CPU Time(s)

為 SQL 語句執行時 CPU 佔用時間總時長,此時間會小於等於 Elapsed Time 時間。單位時間為秒。

  • Executions

SQL 語句在監控範圍內的執行次數總計。如果 Executions=0,則說明語句沒有正常完成,被中間停止,需要關注。

  • Elap per Exec(s)

執行一次 SQL 的平均時間。單位時間為秒。

  • % Total DB Time

為 SQL 的 Elapsed Time 時間佔資料庫總時間的百分比。

  • SQL ID

SQL 語句的 ID 編號,點選之後就能導航到下邊的 SQL 詳細列表中,點選 IE 的返回可以回到當前 SQL ID 的地方。

  • SQL Module

顯示該 SQL 是用什麼方式連線到資料庫執行的,如果是用 SQL*Plus 或者 PL/SQL 連結上來的那基本上都是有人在除錯程式。一般用前臺應用連結過來執行的 sql 該位置為空。

  • SQL Text

簡單的 SQL 提示,詳細的需要點選 SQL ID。

分析說明

如果看到 SQL 語句執行時間很長,而 CPU 時間很少,則說明 SQL 在 I/O 操作時(包括邏輯 I/O 和物理 I/O)消耗較多。可以結合前面 I/O 方面的報告以及相關等待事件,進一步分析是否是 I/O 存在問題。當然 SQL 的等待時間主要發生在 I/O 操作方面,不能說明系統就存在 I/O 瓶頸,只能說 SQL 有大量的 I/O 操作。

如果 SQL 語句執行次數很多,需要關注一些對應表的記錄變化。如果變化不大,需要從前面考慮是否大多數操作都進行了 Rollback,導致大量的無用功。

2.SQL ordered by CPU Time

記錄了執行佔 CPU 時間總和時間最長的 TOP SQL(請注意是監控範圍內該 SQL 的執行佔 CPU 時間總和,而不是單次 SQL 執行時間)。這部分是 SQL 消耗的 CPU 時間從高到底的排序。

  • CPU Time (s)

  • SQL消耗的CPU時間。

  • Elapsed Time (s)

  • SQL執行時間。

  • Executions

  • SQL執行次數。

  • CPU per Exec (s)

  • 每次執行消耗CPU時間。

  • % Total DB Time

  • SQL執行時間佔總共DB time的百分比。

3.SQL ordered by Gets

這部分列出 SQL 獲取的記憶體資料塊的數量,按照由大到小的順序排序。buffer get 其實就是邏輯讀或一致性讀。在 sql 10046 裡面,也叫 query read。表示一個語句在執行期間的邏輯 IO,單位是塊。在報告中,該數值是一個累計值。Buffer Get=執行次數 * 每次的 buffer get。記錄了執行佔總 buffer gets(邏輯 IO)的 TOP SQL(請注意是監控範圍內該 SQL 的執行佔 Gets 總和,而不是單次 SQL 執行所佔的 Gets)。

  • Buffer Gets

  • SQL執行獲得的記憶體資料塊數量。

  • Executions

  • SQL執行次數。

  • Gets per Exec

  • 每次執行獲得的記憶體資料塊數量。

  • %Total

  • 佔總數的百分比。

  • CPU Time (s)

  • 消耗的CPU時間。

  • Elapsed Time (s)

  • SQL執行時間。

篩選 SQL 的標準

因為 statspack/awr 列出的是總體的 top buffer,它們關心的是總體的效能指標,而不是把重心放在只執行一次的語句上。為了防止過大,採用了以下原則。如果有 sql 沒有使用繫結變數,執行非常差但是由於沒有繫結,因此係統人為是不同的 sql。有可能不會被列入到這個列表中。

  • 大於閥值buffer_gets_th的數值,這是sql執行緩衝區獲取的數量(預設10000)。

  • 小於define top_n_sql=65的數值。

4.SQL ordered by Reads

這部分列出了 SQL 執行物理讀的資訊,按照從高到低的順序排序。記錄了執行佔總磁碟物理讀(物理 IO)的 TOP SQL(請注意是監控範圍內該 SQL 的執行佔磁碟物理讀總和,而不是單次 SQL 執行所佔的磁碟物理讀)。

  • Physical Reads

  • SQL物理讀的次數。

  • Executions

  • SQL執行次數。

  • Reads per Exec

  • SQL每次執行產生的物理讀。

  • %Total

  • 佔整個物理讀的百分比。

  • CPU Time (s)

  • SQL執行消耗的CPU時間。

  • Elapsed Time (s)

  • SQL的執行時間。

5.SQL ordered by Executions

這部分列出了 SQL 執行次數的資訊,按照從大到小的順序排列。如果是 OLTP 系統的話,這部分比較有用。因此 SQL 執行頻率非常大,SQL 的執行次數會對效能有比較大的影響。OLAP 系統因為 SQL 重複執行的頻率很低,因此意義不大。

  • Executions

  • SQL的執行次數。

  • Rows Processed

  • SQL處理的記錄數。

  • Rows per Exec

  • SQL每次執行處理的記錄數。

  • CPU per Exec (s)

  • 每次執行消耗的CPU時間。

  • Elap per Exec (s)

  • 每次執行的時長。

6.SQL ordered by Parse Calls

這部分列出了 SQL 按分析次(軟解析)數的資訊,按照從高到底的順序排列。這部分對 OLTP 系統比較重要,這裡列出的總分析次數並沒有區分是硬分析還是軟分析。但是即使是軟分析,次數多了,也是需要關注的。這樣會消耗很多記憶體資源,引起 latch 的等待,降低系統的效能。軟分析過多需要檢查應用上是否有頻繁的遊標開啟、關閉操作。

  • Parse Calls

  • SQL分析的次數。

  • Executions

  • SQL執行的次數。

  • % Total Parses

  • 佔整個分析次數的百分比。

7.SQL ordered by Sharable Memory

記錄了 SQL 佔用 library cache 的大小的 TOP SQL。

  • Sharable Mem (b)

  • 佔用library cache的大小。單位是byte。

8.SQL ordered by Version Count

這部分列出了 SQL 多版本的資訊。記錄了 SQL 的開啟子游標的 TOP SQL。一個 SQL 產生多版本的原因有很多,可以查詢檢視 v$sql_sahred_cursor 檢視瞭解具體原因。對於 OLTP 系統,這部分值得關注,瞭解 SQL 被重用的情況。

  • Version Count

  • SQL的版本數。

  • Executions

  • SQL的執行次數。

9.SQL ordered by Cluster Wait Time

記錄了叢集的等待時間的 TOP SQL。這部分只在 RAC 環境中存在,列出了例項之間共享記憶體資料時發生的等待。在 RAC 環境下,幾個例項之間需要有一種鎖的機制來保證資料塊版本的一致性,這就出現了一類新的等待事件,發生在 RAC 例項之間的資料訪問等待。對於 RAC 結構,還是採用業務分隔方式較好。這樣某個業務固定使用某個例項,它訪問的記憶體塊就會固定地存在某個例項的記憶體中,這樣降低了例項之間的 GC 等待事件。此外,如果 RAC 結構採用負載均衡模式,這樣每個例項都會被各種應用的會話連線,大量的資料塊需要在各個例項的記憶體中被拷貝和鎖定,會加劇 GC 等待事件。

  • Cluster Wait Time (s)

  • 叢集等待時長。

  • CWT % of Elapsd Time

  • 叢集操作等待時長佔總時長的百分比。

  • Elapsed Time(s)

  • SQL執行總時長。

10.Complete List of SQL Text

這部分是上面各部分涉及的 SQL 的完整文字。

六、Instance Activity Statistics

1.Instance Activity Stats

這部分是例項的資訊統計,專案非常多。對於 RAC 架構的資料庫,需要分析每個例項的 AWR 報告,才能對整體效能做出客觀的評價。

CPU used by this session

這個指標用來上面在當前的效能採集區間裡面,Oracle 消耗的 CPU 單位。一個 CPU 單位是 1/100 秒。從這個指標可以看出 CPU 的負載情況。

案例 - 分析系統 CPU 繁忙程度

在 TOP5 等待事件裡,找到"CPU time",可以看到系統消耗 CPU 的時間為 26469 秒。

在例項統計部分,可以看到整個過程消耗了 1813626 個 CPU 單位。每秒鐘消耗 21 個 CPU 單位,對應實際的時間就是 0.21 秒。也就是每秒鐘 CPU 的處理時間為 0.21 秒。

系統內 CPU 個數為 8。每秒鐘每個 CPU 消耗是 21/8=2.6(個 CPU 單位)。在一秒鐘內,每個 CPU 處理時間就是 2.6/100=0.026 秒。

*總體來看,當前資料庫每秒鐘每個 CPU 處理時間才 0.026 秒,遠遠算不上高負荷。資料庫 CPU 資源很豐富,遠沒有出現瓶頸。

七、IO Stats

1.Tablespace IO Stats

表空間的 I/O 效能統計。

  • Reads

  • 發生了多少次物理讀。

  • Av Reads/s

  • 每秒鐘物理讀的次數。

  • Av Rd(ms)

  • 平均一次物理讀的時間(毫秒)。一個高相應的磁碟的響應時間應當在10ms以內,最好不要超過20ms;如果達到了100ms,應用基本就開始出現嚴重問題甚至不能正常執行。

  • Av Blks/Rd

  • 每次讀多少個數據塊。

  • Writes

  • 發生了多少次寫。

  • Av Writes/s

  • 每秒鐘寫的次數。

  • Buffer Waits

  • 獲取記憶體資料塊等待的次數。

  • Av Buf Wt(ms)

  • 獲取記憶體資料塊平均等待時間。

2.File IO Stats

檔案級別的 I/O 統計。

八、Advisory Statistics

顧問資訊。這塊提供了多種顧問程式,提出在不同情況下的模擬情況。包括 databuffer、pga、shared pool、sga、stream pool、java pool 等的情況。

1.Buffer Pool Advisory

Buffer pool 的大小建議。

  • Size for Est (M)

  • Oracle估算Buffer pool的大小。

  • Size Factor

  • 估算值與實際值的比例。如果0.9就表示估算值是實際值的0.9倍。1.0表示buffer pool的實際大小。

  • Buffers for Estimate

  • 估算的Buffer的大小(數量)。

  • Est Phys Read Factor

  • 估算的物理讀的影響因子,是估算物理讀和實際物理讀的一個比例。1.0表示實際的物理讀。

  • Estimated Physical Reads

  • 估計的物理讀次數。

2.PGA Memory Advisory

PGA 的大小建議。

  • PGA Target Est (MB)

  • PGA的估算大小。

  • Size Factr

  • 影響因子,作用和buffer pool advisory中相同。

  • W/A MB Processed

  • Oracle為了產生影響估算處理的資料量。

  • Estd Extra W/A MB Read/ Written to Disk

  • 處理資料中需要物理讀寫的資料量。

  • Estd PGA Cache Hit %

  • 估算的PGA命中率。

  • Estd PGA Overalloc Count

  • 需要在估算的PGA大小下額外分配記憶體的個數。

3.Shared Pool Advisory

建議器通過設定不同的共享池大小,來獲取相應的效能指標值。

  • Shared Pool Size(M)

  • 估算的共享池大小。

  • SP Size Factr

  • 共享池大小的影響因子。

  • Est LC Size (M)

  • 估算的庫快取記憶體佔用的大小。

  • Est LC Mem Obj

  • 快取記憶體中的物件數。

  • Est LC Time Saved (s)

  • 需要額外將物件讀入共享池的時間。

  • Est LC Time Saved Factr

  • 物件讀入共享池時間的影響因子。

  • 表示每一個模擬的shared pool大小對重新將物件讀入共享池的影響情況。當這個值的變化很小或不變的時候,增加shared pool的大小就意義不大。

  • Est LC Load Time (s)

  • 分析所花費的時間。

  • Est LC Load Time Factr

  • 分析花費時間的影響因子。

  • Est LC Mem Obj Hits

  • 記憶體中物件被發現的次數。

4.


建議器對 SGA 整體的效能的一個建議。

  • SGA Target Size (M)

  • 估算的SGA大小。

  • SGA Size Factor

  • SGA大小的影響因子。

  • Est DB Time (s)

  • 估算的SGA大小計算出的DB Time。

  • Est Physical Reads

  • 物理讀的次數。

九、Latch Statistics

1.Latch Activity

Get Requests/Pct Get Miss/Avg Slps /Miss

表示願意等待型別的 latch 的統計資訊。

NoWait Requests/Pct NoWait Miss

表示不願意等待型別的 latch 的統計資訊。

Pct Misses

比例最好接近 0。

十、Segment Statistics

col 1col 2

  | <sectionstyle="margin:-9px 0px 0px; padding: 0px; border-color: rgb(30, 155, 232); text-align: center; color: rgb(255, 255, 255); font-weight: bold; text-decoration: inherit; box-sizing: border-box;">                                                                                                                                                                                                                                                                                           | <section style="margin:0pxauto;padding: 0px; width: 0px; height: 8px; color: inherit; border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-bottom-width: 0.4em; border-bottom-style: solid; box-sizing: border-box; border-right-color: transparent !important; border-left-color: transparent !important; border-right-width: 0.3em !important; border-left-width: 0.3em !important; border-right-style: solid !important; border-left-style: solid !important;"></section>  | </section>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

1.Segments by Logical Reads

2.Segments by Physical Reads

段的物理讀情況。

3.Segments by Buffer Busy Waits

從這部分可以發現那些物件訪問頻繁。Buffer Busy Waits 事件通常由於某些資料塊太過頻繁的訪問,導致熱點塊的產生。

4.Segments by Row Lock Waits

AWR 報告 Segment Statistics 部分的 Segments by Row Lock Waits,非常容易引起誤解,它包含的不僅僅是事務的行級鎖等待,還包括了索引分裂的等待。之前我一直抱怨為什麼 v$segment_statistics 中沒有統計段級別的索引分裂計數,原來 ORACLE 已經實現了。但是統計進這個指標中,你覺得合適嗎?

十一、其他問題

col 1col 2

  | <sectionstyle="margin:-9px 0px 0px; padding: 0px; border-color: rgb(30, 155, 232); text-align: center; color: rgb(255, 255, 255); font-weight: bold; text-decoration: inherit; box-sizing: border-box;">                                                                                                                                                                                                                                                                                           | <section style="margin:0pxauto;padding: 0px; width: 0px; height: 8px; color: inherit; border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); border-bottom-width: 0.4em; border-bottom-style: solid; box-sizing: border-box; border-right-color: transparent !important; border-left-color: transparent !important; border-right-width: 0.3em !important; border-left-width: 0.3em !important; border-right-style: solid !important; border-left-style: solid !important;"></section>  | </section>