【SQL】Oracle SQL monitor

kunlunzhiying發表於2018-01-30


【SQL】Oracle SQL monitor




第一章 被埋沒的SQL最佳化利器——Oracle SQL monitor

DBAplus社群 | 2015-11-26 07:00

轉載宣告:本文為DBA+社群原創文章,轉載必須連同本訂閱號二維碼全文轉載,並註明作者名字及來源:DBA+社群(dbaplus)。

據說,在Oracle企業版資料庫中有一個免費的工具,乃SQL最佳化之利器,那就是Oracle SQL monitor。下面,由DBA+社群原創專家周俊,給大家科普一下這一被埋沒的神器。

周俊

DBA+社群原創專家

具有14年以上Oracle資料庫技術支援經驗,在IBM的7年間擔任華東區非IBM logo產品技術支援團隊team leader,同時是IBM中國區Oracle 軟體支援服務的技術負責人。目前任職於Oracle公司,專注於Oracle資料整合方案設計和實施。獲得Oracle 8i~11g OCP、Oracle 10g OCM、DB2 administrator、PMP等證書。

一前言

說實話,我以前也不太愛用花哨的圖形介面工具進行SQL最佳化,最近參加了Oracle RWP培訓,我發現Oracle 11g 引入的SQL monitor確實蠻好用的,是個被埋沒的SQL最佳化利器。最重要的是Oracle SQL monitor在Oracle企業版資料庫中是免費供大家使用的。下面我和大家分享如何利用SQL monitor簡化我們的SQL最佳化工作。

二如何開啟SQL monitor report

方法一

Step1:開啟Oracle EM console主頁,切換到效能頁面,點選右下角的SQL監控。

wps2D39.tmp

wps2D49.tmp

Step2:選擇 時間範圍,可以按照持續時間或者資料庫時間對SQL語句進行排序。

wps2D5A.tmp

在Oracle 11g中,當SQL滿足以下條件之一就會被sql monitor捕獲到,監控資料被記錄在v$sql_monitor檢視中。

當SQL並行執行時,會立即被實時監控到

當SQL單程式執行時,如果消耗超過5秒的CPU或I/O時間,它也會被監控到

使用/*+ monitor */提示的sql語句

Step3:選擇您想要進行SQL最佳化語句前,點選第一列狀態列中勾號,Oracle就會將該SQL語句的執行情況華麗麗的展現在您面前。

wps2D5B.tmp

方法二

在效能頁面左下角的頂級會話中,點選您想要檢視的SQL語句ID。

wps2D6C.tmp

在SQL監控頁面點選第一列狀態列中的圖示。

wps2D7C.tmp

方法三

如果您沒有配置Oracle EM,但是知道待最佳化SQL語句對應的SQLID,可以透過以下指令碼利用SQL monitor檢視SQL語句在資料庫中真實的執行計劃。

在SecureCRT中啟用log跟蹤,選擇儲存的日誌檔案(字尾html)

在SQLPLUS 中執行

set trimspool on

set arraysize 512

set trim on

set pagesize 0

set linesize 1000

set long 1000000

set longchunksize 1000000

spool sqlmon.html

select /*+ noparallel */ dbms_sqltune.report_sql_monitor (sql_id=>'input your SQL ID', report_level=>'ALL', type=>'ACTIVE') from dual;

spool off

cat sqlmon.html

在SecureCRT中關閉log跟蹤,開啟儲存的檔案就可以看到SQL執行計劃了。

三如何利用SQL monitor進行SQL最佳化

使用SQL monitor開啟SQL執行計劃後,

我們通常會根據最右邊CPU和wait的activity,找到SQL執行計劃中資源消耗較高的步驟。

然後檢視一下Oracle估算的返回行數和實際的返回行數是否相差很大,如果估算的行數和實際的行數相差不大,至少表明目前對應資料庫物件上的統計資訊是準確的。

本例中Oracle估算的返回行數和實際返回行數相差不大,Oracle最佳化器採用了布隆過濾和HASH 右連的執行計劃,接下去我們通常會檢查SQL的篩選條件,判斷是否使用了正確的索引等最佳化手段,這裡我就不一一展開了。

wps2D7D.tmp

wps2D8E.tmp

下面是我最近遇到的一個利用SQL monitor進行快速SQL最佳化的案例分享。

SQL Text:SQL語句比較長 ,我截選了其中部分有代表性的SQL。

wps2D9E.tmp

利用SQL monitor我們可以在執行計劃中快速的定位需要重點關注的步驟。

wps2DAF.tmp

我們看到該SQL語句已經執行了5.4小時,Oracle估算的返回行數和實際行數相差非常大,表明相關表上的統計資訊不準確。

我們對DMS_CONTAINERS和DMS_CONTAINER_JN表進行了統計資訊收集,統計資訊重新收集後Oracle馬上使用了DMS_CONTAINER_JN表上正確的IYC_CNTRID欄位的索引,但是DMS_CONTAINERS表上仍舊使用了選擇度不高TYPE欄位索引。

進一步檢視SQL語句,我們發現該SQL是透過檢視YMS_GUI_LOAD_CONTAINERS_VW訪問DMS_CONTAINERS表,該檢視的定義如下:

wps2DB0.tmp

由於在檢視where條件中有IYC_TYPE欄位,Oracle優先選用IYC_TYPE欄位上的索引對DMS_CONTAINERS表進行訪問,在CBO下,Oracle不會再去自動選擇其他欄位上單獨的索引進行訪問(除非手工設定AND-EQUAL提示),因此沒有選擇篩選度更高的YC_LSTUPDDT欄位上的索引。 如果需要Oracle使用到其他欄位上的索引,最簡單的方法就是在IYC_TYPE和YC_LSTUPDDT欄位上建立聯合索引,Oracle在分析索引列的時候自動會分析兩個列的組合情況,從而選擇該複合索引。

wps2DC1.tmp

四總結

透過前面的介紹相信大家對Oracle SQL monitor華麗、直觀的介面留下了深刻的印象,下面我再總結一下使用Oracle SQL monitor進行SQL最佳化的步驟:

透過SQL monitor監控我們可以快速地發現異常執行的SQL語句,如果您知道SQL對應的SQL ID也可以透過指令碼利用SQL monitor檢視SQL語句在資料庫中真實的執行計劃。

檢視SQL執行計劃,透過CPU和WAIT的活動比重快速找到SQL執行計劃中的關鍵步驟。

透過比較Oracle估算的行數和實際返回行數能夠快速判斷是否需要重新收集統計資訊,幫助我們分析Oracle最佳化器選擇的SQL執行計劃有無問題。

具體的SQL最佳化方法大家可以參考之前丁俊大師在DBA+社群分享過的Oracle SQL最佳化專題(關注DBA+社群微信公眾號:dbaplus,回覆“001”即可檢視此文),我在這就不做進一步展開啦。

工欲善其事,必先利其器。小夥伴們,還等什麼呢,趕緊去試試Oracle SQL monitor這個被埋沒的SQL最佳化利器吧!




 SQL Monitor,你值得掌握的一個特性 
    對於線上的SQL語句,看著執行計劃cost還不錯,但是實際執行的時候效果卻有千壤之別,這是為什麼呢?
    對於一個龐大的SQL語句,看著得到的執行計劃卻不知道瓶頸在哪裡,SQL語句太複雜,但是執行計劃更復雜,要讀明白它掌握要領也不是一件容易的事情。
    碰到很多朋友問我,怎麼去讀一個執行計劃,這個無論說的怎麼細,似乎都不是很容易去理解,語言描述,純文字描述和圖形的效果還是有很大的差別。
    如果你在11g的版本中,SQL Monitor就是一個大大的福利,你值得掌握,如果你還沒有好好掌握它,就實在太可惜了。
至於SQL Monitor更多的細節就不一一描述了,11g推出的這個特性其實和MySQL裡的慢日誌有些類似,MySQL裡面的閾值要更低一些,SQL Monitor是5秒。一旦達到這個標準,就會進收集到v$sql_monitor這個檢視中,可以得到詳細的會話資訊和執行計劃。
    如果想單獨定製,那麼也不是一件難事。可以使用hint monitor來完成。比如這樣的形式
select /*+ monitor */ count(*) from emp where  xxxxx
    如果確認不需要放入監控範圍,也可以使用no_monitor來定製,比如這樣的形式
select /*+ no_monitor */ count(*) from emp where  xxxxx
    檢視生成的監控資訊,可以使用如下的方式:
select dbms_sqltune.report_sql_monitor from dual;
    當然這些都是SQL Monitor常規的一些知識點,這些還不足以讓我興趣大開。我感興趣的是它強大的UI展現能力。當然聽起來這個似乎和這個特性好像關聯不大,你看到效果就知道了。一個很複雜,抽象的事物如果用圖形表示,要比文字豐富形象的多。
    得到SQL Monitor的報告,大體有以下幾種格式。TEXT,HTML,ACTIVE三種
我們打一個比方。很多手機都會按照配置來冠以各種名號。



SQL Monitor的報告也是如此,TEXT格式是標準版,HTML是高配版,ACTIVE是尊享版
我們不來虛的,來實際看看效果。

文字格式的效果如下:


HTML格式的效果如下:
執行概覽,會話資訊,執行計劃一目瞭然,非常貼心。

那麼ACTIVE格式是什麼意思呢,大體就是最炫,最全面的效果,還有一個小的flash效果。


有的朋友可能看到會說,這和HTML的效果有啥差別啊,有的,我再給一張圖。
執行計劃原來可以這麼讀。全表掃描,索引掃描,表連線資訊都一目瞭然,越是複雜的執行計劃這種方式越省事。


SQL文字和繫結變數的資訊,點選SQL_ID就會彈出一個小視窗來。

好吧,看起來這麼炫,想得到這個報告難不難呢,很簡單就一個SQL語句就能搞定,絕對沒有標題黨的意思。
如果想寫成shell指令碼,也就是嵌入一個SQL語句即可。
tmp_sql_id=$1
sqlplus -s  / as sysdba<<eof
set pages 0
set long 99999999
set linesize 300
col comm format a200
set long 99999
SELECT dbms_sqltune.report_sql_monitor(
sql_id => '${tmp_sql_id}',
report_level => 'ALL',
type=>'TEXT',
base_path =>''
) comm 
FROM dual;
EOF
唯一的差別就是在type的地方。TEXT,HTML的就設定為TEXT,HTML即可。如果是ACTIVE格式的,這個我們得稍說一些背景。
這個功能在Enterprise Manager中檢視是很自然的一件事情,如果沒有安裝EM,我們不能因為這個專門去部署一個EM來不是。要達到同樣的效果,就需要連線網路下載相應的格式,當然退一步來說,要做以下的一些輔助工作,還可以下載幾個指令碼到本地即可。
比如我們設定一個本地的目錄結構,設定類似的站點 jeanron100
就需要在本地建立一個jeanron100的目錄
mkdir -p jeanron100/sqlmon
然後下載相應的指令碼
wget --mirror --no-host-directories --cut-dirs=1
wget --mirror --no-host-directories --cut-dirs=1
wget --mirror --no-host-directories --cut-dirs=1 http://download.oracle.com/otn_software/emviewers/scripts/document.js
wget --mirror --no-host-directories --cut-dirs=1
生成SQL語句的active報告語句如下:
SELECT dbms_sqltune.report_sql_monitor(
sql_id => '${tmp_sql_id}',
report_level => 'ALL',
type=>'ACTIVE',
base_path =>''
) comm 
FROM dual;
把複製到的結果以HTML格式儲存,在本地的目錄下開啟即可。其實感興趣可以讀一下里面的內容,裡面大量使用了xml解析的方式。效果還是蠻不錯的。值得推薦。
</eof<>




第一章  掌握SQL Monitoring這些特性,SQL最佳化通通不在話下

DBAplus社群 | 2015-12-29 07:01

轉載宣告:本文為DBA+社群原創文章,轉載必須連同本訂閱號二維碼全文轉載,並註明作者名字及來源:DBA+社群(dbaplus)。

目錄

術語說明

概述

什麼SQL會被SQL MONITORING監控到

找到Real Time SQL Monitoring入口

詳解Real Time SQL Monitoring

1術語說明

在正式介紹Real Time SQL Monitoring之前,我們先對接下來要用到一些術語做集中的介紹。

Table Queue,訊息緩衝區,在並行操作中使用,用於PX程式之間的通訊,或者PX程式與QC程式之間的通訊,是記憶體中的一些page,每個訊息緩衝區的大小由引數parallel_execution_message_size控制,11GR2版本預設為16K,之前的各個大版本這個值都不一樣,詳細請參考ORACLE官方文件。

牆面時間、持續時間指的是物理時間、鐘錶時間。

HASH JOIN左邊,the build side of hash join,一般為小表。

HASH JOIN右邊,the probe side of hash join,一般為大表。

M代表百萬

行源 row source,指的是執行計劃特定的一行操作,例如:

wps847F.tmp

上面執行計劃的第一列,Id列0-5,每一行都是一個行源

2概述

Oracle每個版本總有一些新特性驚豔到我們,SQL MONITORING對我來說就是這樣一個新特性,雖然它還未廣為人知,它在11GR1版本被提供,而且後續的幾個版本(11GR2,12CR1)這個功能也被不斷的加強,說明ORACLE對它非常的重視,它能夠把查詢涉及到的所有關鍵效能統計資訊集中在一個頁面上,特別是對於並行查詢的語句會自動啟用這個特性。這個功能在國外的ORACLE 使用者組被多次的分享,但是目前國內對它的介紹還非常少,本文主要介紹Oracle Real Time SQL Monitoring的核心特性,意圖使DBA能夠有一種新的手段(更先進的手段)來診斷SQL效能,進而提升最佳化效率。

SQL最佳化是一個DBA必備的技能,然而即使一個有豐富SQL最佳化經驗的老DBA估計碰到幾十行甚至上百行的執行計劃也要皺皺眉頭,他如何能快速知道:

在這麼龐大的執行計劃中哪一行源消耗的資源最多。如果一個SQL的執行計劃包含5個行源,行源1消耗的DB TIME佔取了3%,那你即使把這3%的DB TIME全部消滅掉,也只讓SQL的效能提升了3%,對於整體的DB TIME提升效果並不明顯。

如何知道整個SQL執行過程中消耗的哪一類資源最多,IO?CPU?,這讓我們對SQL的效能有一個整體的認識,你可能觀察效能指標後會說,奧,這是一個IO比較重的SQL,如果需要大幅提升SQL效能,也許要考慮提升資料庫系統IO的能力。

對於一個正在執行的SQL語句,如何知道它當前執行到哪一步了?甚至知道執行完這一步還需要多久?

如何知道執行這個SQL語句都經歷了哪些等待事件,甚至知道這些等待裡哪一類等待最為嚴重?

要想知道這些問題的答案,在11G之前都是非常不容易的,要透過各種V$檢視的關聯去獲取,而且展示的結果不夠一目瞭然。 11G以後這些資訊全部可以在SQL MONITORING中找到答案,SQL MONITORING提供的功能還不僅僅是上面提到的這些,透過SQL MONITORING還可以輕鬆獲取語句的繫結變數、監控索引的整個建立過程及建立完索引剩餘的工作量。 文字會著重講解SQL MONITORING的核心功能,其他的相關資訊就請讀者們去盡情挖掘吧。

3什麼SQL會被SQL MONITORING監控到

對於絕大多數OLTP系統來說,SQL相對比較簡單,每次的執行時間都非常快,絕大部分SQL的響應時間都應該在10MS以下,最佳化的複雜度也比較低,SQL MONITORING功能的出現並不是為了幫助DBA發現、診斷OLTP SQL的效能問題,而是為了加快DBA最佳化資料倉儲類SQL的效率,這些SQL是偏OLAP系統的,特點是併發量低、執行時間久、SQL複雜度高。滿足以下條件的任意SQL都會被SQL MONITORING監控到:

如果序列執行的SQL,消耗的CPU時間或IO時間超過5秒,那麼這些SQL 將會被監控到,透過修改隱含引數_sqlmon_threshold可以控制這一行為,預設為5秒,如果設定為0將關閉SQL MONITORING功能 。注意我這裡提到的是SQL消耗的CPU時間或IO時間,而不是SQL的執行時間,之所以需要限制CPU時間或IO時間是為了防止資料庫某一時刻如果有大量lock/latch的話,那麼將有大量的SQL滿足5秒執行時間的條件,而SQL監控本身比較消耗資源,需要複製執行時的效能統計資訊到SGA,每一個受監控的SQL都有一個單獨的記憶體結構,在11G可能會導致大量的latch競爭,CPU飆高,12C對這個問題做了最佳化不存在該問題了。如果你發現你的SQL執行時間明顯超過了5秒但是卻沒被SQL MONITORING監控到,那麼你該仔細檢查是否是由於SQL本身消耗的CPU或IO並沒有超過5秒(由於鎖、網路?)。

並行執行的SQL將全部被監控到,不需要等待CPU或IO時間超過5秒。對於這一點也比較好理解,一般並行查詢的SQL都是報表類或比較重的任務類的SQL,因此會自動開啟SQL MONITORING的功能。

增加HINT /+ monitor /的SQL會立即開啟SQL MONITORING功能。

除了以上條件外,你還需要檢查一些系統引數是否設定正確:

statistics_level需要為TYPICAL(預設)或者ALL.

control_management_pack_access需要為DIAGNOSTIC+TUNING(預設)

SQL MONITORING並不會監控非常大的執行計劃,預設不會監控超過300行的執行計劃,可以透過隱含引數_sqlmon_max_planlines來控制。具體請參照MOS ID:1613163.1

4找到Real Time SQL Monitoring入口

可以從這幾個位置找到、使用SQL Monitoring的功能:

Enterprise Manager

Enterprise Manager Cloud Control(EMCC)

SQL Developer

DBMS_SQLTUNE包

這裡我們主要介紹透過Enterprise Manager Cloud Control(EMCC)頁面來使用Real Time SQL Monitoring,文章的後面也會有單獨一節簡單介紹如何透過SQL包DBMS_SQLTUNE來獲取Real Time SQL Monitoring的輸出。

首先登陸Oracle EMCC,進入到【資料庫】頁面,選擇你需要監控的資料庫,這裡以clouddb1為例:

wps8480.tmp

進入到clouddb1資料庫後,選擇【效能】下的SQL監視功能。

wps8491.tmp

然後就進入到了SQL MONTORING的主介面,這裡包含了最近被監控到的SQL,檢視狀態列,可以知道SQL當前的執行狀態。

wps84A2.tmp

狀態列一般包含以下4種狀態:執行、完成、排隊、錯誤,將滑鼠放在狀態列的符號上面,會看到符號所代表的狀態。這幾個狀態除了【排隊】狀態都比較好理解,排隊這個狀態只會在大於11GR2版本出現。ORACLE 11GR2在並行設定方面起了很大變化:自動並行度調整、並行語句佇列、記憶體並行執行,啟用此三項新特性需要設定引數parallel_degree_policy為auto,預設值為MANUAL。設定為auto後,三項新特性全部被開啟,這裡我們主要說下並行語句佇列,啟用該特性後,透過設定parallel_servers_target來指定總的可用的並行子程式的目標數,執行語句時,如果發現可用的並行程式數已經小於待執行語句的目標數,那麼語句將會放入佇列中等待直到擁有足夠可用的並行程式。一旦被加入佇列,你就會在SQL MONITORING的監控頁面上看到,語句的當前執行狀態為【排隊】。

SQL監視頁面顯示的SQL列表不是針對特定的SQL文字的,而是針對特定SQL語句的一次特定的執行,因此如果兩個會話執行相同的語句,你會在此列表中看到兩個單獨的條目,因此它與v$sql的表現行為不一樣,如果2個會話在執行同一個SQL,在 v$sql裡只能對應到彙總了SQL執行統計資訊的一個記錄。針對SQL MONITOR的這個特點,允許你針對一個特定的使用者(他正在抱怨效能問題)檢查這個語句到底出了什麼問題,而不是首先觀察彙總了所有使用者的語句級的效能指標,像v$sql裡的,再試著從中發現你所關注的使用者問題。

5詳解Real Time SQL Monitoring

找到Real Time SQL Monitoring的入口後,可以點選SQL_ID進入到Real Time SQL Monitoring的展示頁面,是不是很炫酷?

wps84B2.tmp

也許你對頁面上的很多指標還感覺很陌生,彆著急,我接下來會對頁面上的核心部分進行介紹。

5.1 一般資訊

wps84C3.tmp

一般資訊部分顯示了SQL執行的一些基本的細節,例如SQL的文字,SQL語句採用的並行度,SQL的執行開始時間,本次統計值最後一次的重新整理時間,執行SQL的使用者、取數操作等。注意【SQL文字】後帶有…的標記(紅色框標記),點選它,你會獲得完整的SQL語句文字,從版本11.2.0.2開始,你還會看到繫結變數的值。

例如:

wps84C4.tmp

上面的程式碼我對一個帶有繫結變數的SQL以並行度6執行了查詢,然後透過EMCC的SQL MONITORING頁面點選【SQL文字】後面部分的…,這時會出現一個新視窗:

點選show SQL Binds:

wps84C5.tmp

這時就可以看到繫結變數的列表,是不是非常的方便?

當然就像上面提到的,SQL MONITORING主要用於監控資料倉儲型別的SQL,對於長時間執行查詢,是否應該使用繫結變數是另外一個單獨的話題,在資料倉儲中,一般的最佳實踐為:不該為長時間執行的查詢使用繫結變數,因為相對於整個SQL的執行時間,SQL解析只佔到可以忽略不計的時間,而且資料倉儲的系統本身的SQL執行頻率也非常低,因此我們可以考慮對所有查詢都進行硬解析,即使這樣會消耗掉一些響應時間(可以忽略不計),但我們儘可能保證每一組引數組合都能生成一個最優的執行計劃,因為就繫結變數和文字常量來說,文字常量是最適合產生最優執行計劃的。

言歸正傳,就像上面已經演示的,得到被監控查詢的繫結變數值在Oracle 11.2.0.2或更高版本上變得容易,以前你可能需要查詢v$sql_bind_capture,dba_hist_sqlbind來獲取繫結變數的值(歷史繫結值),甚至透過oradebug errorstack這類命令來獲得當前執行SQL的正在使用的繫結變數的值,現在你終於可以拋棄這些方法了。

【一般資訊】模組還包含了取數操作(fetch calls)的次數,簡單來說它代表了資料庫和應用端網路互動的次數,如果是count,sum這類操作,一般這個值為1,只需要一次網路互動,但是對於select *這樣的查詢,返回的資料量越大,這個值也會越大。

wps84D6.tmp

例如從上圖我們知道,返回1000條記錄一共分了11次才傳輸完成。每次傳輸90條記錄。

取數操作我們在後面的章節還會繼續講到,這裡先點到為止。

5.2 時間和等待統計資訊

wps84D7.tmp

這一部分內容非常少,但是資訊量非常大,顯示的是持續時間、資料庫時間和等待活動百分比。把滑鼠移動到資料庫時間的條狀圖上,會看到消耗在各類等待事件和CPU上的時間,這讓你知道你的SQL時間都花哪了,是IO操作多,還是CPU操作多,這非常的棒。等待活動百分比條狀圖則顯示了詳細的等待事件分佈,例如上圖中藍色部分代表整個語句執行過程中,45%的等待發生在direct path read temp這個等待事件上,注意這裡等待活動百分比條狀圖的100(100%)指的是資料庫裡的等待事件時間,而不是整個資料庫時間,即並不包括CPU時間,這部分的資訊可以告訴DBA在SQL執行過程中,遭遇了哪些等待事件,以及這些等待事件佔取的比例,當然,你應該關注這些等待事件裡最為惹眼的。

你可能對持續時間和資料庫時間的含義感到疑惑,沒關係,我們接下來就會著重介紹這兩個時間代表的含義和兩者的差異:

5.3 持續時間

持續時間(牆面時間)是使用者非常關注的時間,它顯示一個語句已經處於活動狀態多久,它代表著語句從開始執行直到結束的時間跨度,對於正在執行的語句,則是從開始執行到當前的時間。當然,終端使用者可能還要等待更長的時間,因為除了資料庫的響應時間之外,時間還可能會被花在應用系統上,或者是資料庫和應用伺服器之間的網路上。例如SQL的持續時間為5秒,但是應用本身處理這些資料需要1秒,那麼使用者端感受到的時間就可能是6秒,而不是資料庫端看到的持續時間5秒。

需要再次強調的是,持續時間衡量的是從SQL開始執行即遊標開啟直到遊標被關閉或取消的時間跨度,這意味著如果資料庫1分鐘內完成一個查詢,但隨後產生的數百萬結果每次只能返回幾行,從應用的角度看,這個查詢將需要很長的時間(需要數百萬次的網路傳輸)才能完成,但是資料庫端只花了一點時間來處理。對於網路傳輸的情況,SQL MONITORING會有一個指標進行反應,就是上面已經提到過的取數操作(fetch calls),如果網路傳輸量比較大的話,這個值會比較大。

wps84D8.tmp

例如我透過monitor這個hint強制讓ORACLE監控這個SQL,這個SQL會返回大量的結果集給客戶端,我們透過EMCC來監控這個SQL的相關監控資訊:

wps84D9.tmp

取數操作值非常大,因為資料庫要跟應用(我們這裡是SQLPLUS客戶端)有大量的網路互動。

5.4 資料庫時間

資料庫時間即DB Time,顯示的是一個查詢在資料庫中執行花費的總時間,就DML操作來說,一般資料庫時間基本等於持續時間,因為DML操作不用返回結果集,沒有網路互動時間,但是如果執行的是一個SELECT語句並返回很多行,那麼持續時間一般會大於資料庫時間,因為很多的網路時間會被統計在持續時間中,資料庫會把資料分批傳送給應用程式,因此對於一個select語句你可能會看到資料庫時間只有30秒,而持續時間卻有50秒,其中30秒用於服務你的請求,其餘的時間資料庫則是空閒的,等待應用取下一批資料。我們再次看一下上面已經使用過的一張圖,對於這個查詢來說,由於要返回大量的結果集給客戶端,因此持續時間遠遠大於資料庫時間。

wps84E9.tmp

對於序列查詢來說,持續時間都是大於等於資料庫時間的,但是對於並行查詢來說,情況有所改變:當執行一個並行查詢時,會有多個伺服器程式(甚至可能是多個伺服器上的伺服器程式)參與進來,每個伺服器程式都可以使用單獨的CPU資源,也就是1分鐘的牆面時間(wall time),但是資料庫時間可能有1*N分鐘(N為CPU邏輯核數),並行查詢最終的資料庫時間可能會比持續時間(wall time)長的多。

wps84EA.tmp

這個語句的持續時間只有19秒,而資料庫時間則有1.8分鐘,從【一般資訊】的Execution Plan部分可以看到這個語句是以並行度6來執行,這意味著資料庫裡有多個程式同時服務於這個查詢,所有這些會話的資料庫時間加上協調程式的時間都被彙總到了資料庫時間中。資料庫時間代表著大致有多少時間必須在資料庫中完成,但是因為該語句是並行的,因此你其實不必等待那麼長的時間。

5.5 IO統計資訊

wps84EB.tmp

顯示了語句執行時的一些關鍵的IO統計資訊。

緩衝區獲取數,即buffer gets,顯示了資料庫層的邏輯IO總數。IO請求包含了總的IO請求次數,例如db file sequential read,db file scattered read,direct path read等等的次數,IO位元組代表了讀取/寫入的IO的總位元組數。透過條狀圖的不同有顏色部分,能獲取到更詳細的統計值,例如上圖中顯示10GB的IO位元組,其中有42%是讀取請求產生的,等等。 需要注意的是,這裡的IO請求次數和IO位元組數統計可能超出你的預期,例如針對一個1G表的全表掃描按照某個欄位排序,不但要統計表本身的IO,而且還要統計排序產生的讀、寫臨時段的IO。

5.6 詳細資訊

wps84FC.tmp

詳細資訊頁本身包含了一些子tab頁面,例如上圖中包含了【計劃統計資訊】、【計劃】、【並行】、【活動】、【度量】子tab頁。詳細資訊頁主要包含了執行計劃在在行源(rowsource)細節上的一些統計資訊。

首先我們先看下頁面的最左側一列,如果某個行源操作是被並行執行的,會用多個小人的圖示標識,相反如果是被序列執行的會用一個小人的圖示標識,如果你觀察仔細的話,會發現多個小人的圖示有時也會有顏色的區分(下圖),這是因為並行執行中,生產者和消費者角色的不同導致的。例如圖中的紅色是生產者負責掃描表,而圖中藍色的程式是消費者負責把接收過來的資料做排序。

再者,我們會看到多人小圖示的後面有向右箭頭的指示,這個代表了目前的查詢正在進行,執行計劃正在執行到這個(些)行源(右箭頭所在的行源),也就是透過SQL MONITORING可以知道目前執行計劃執行到了哪一個行源,nice job!如果SQL執行結束,或者這個(些)行源執行結束,這些向右的小箭頭也會消失。

wps850C.tmp

然後我們關注下【估計行數】和【實際行數】,如果兩者差異巨大,可能是由於你的資料庫系統統計資訊缺失或者陳舊,或者是最佳化器自身的演算法導致。這裡我並不會介紹CBO最佳化的相關資訊,讀者可以自行參閱相關文章。【實際行數】列真實的反應了掃描程式需要產生的工作量。

雖然Oracle CBO技術發展了這麼久,相關書籍、文章也非常多,但是筆者認為,閱讀、瞭解CBO最好的書籍仍然是jonathon lewis的基於成本的ORACLE最佳化法則,不過中文版貌似已經買不到了。


【時間表列】(Timeline)是一個很重要的列,透過它可以知道這個SQL執行計劃每一行活躍的時間段。上圖中的Timeline列基於執行計劃每一行的活動構造出了一個視覺化的時間進度圖,它基於ASH的取樣,從ORACLE 11G開始,ASH基於SQL執行計劃的每一行源收集資訊,觀察上圖中Timeline列標題裡的括號內的數字,它顯示了這個SQL總的執行持續時間,在這裡是21秒,現在很容易根據這個,然後觀察每個行源上的條狀圖和條狀圖位置進行視覺化的解析。 然後將我們的目光移動到【臨時】列,它代表了SQL執行過程中消耗的臨時表空間大小,如果發現SQL消耗的臨時表空間非常大,可以檢視是否並行度不夠或者PGA引數設定過小,不過對於建立索引、大表HASH JOIN、SQL排序等操作來說,完全避免臨時段的使用也是一件可望不可即的事。


【IO請求】列代表了每一個行源所產生的IO請求數,根據視覺化的條形圖,很容易發現哪一個行源產生了最多的IO請求。


【活動百分比】列代表了在此行源產生的等待,CPU也會被統計在內,它的資料是從ASH的基表v$active_session_history獲取的,也就是說資料是取樣而來的(1秒取樣一次)。例如:


wps850D.tmp


wps851E.tmp


wps851F.tmp


11G的v$active_session_history檢視新增了SQL_PLAN_LINE_ID、SQL_PLAN_OPERATION、SQL_PLAN_OPERATION列,可以跟蹤到具體發生等待的行源資訊,非常有利用與DBA做效能診斷。上面SQL執行過程中,ASH共取樣到了6條資料,其中五次等待事件為direct path read,一次為空,即為CPU操作。 SQL_PLAN_LINE_ID 代表產生等待的行源,這裡為6,觀察下圖【行ID】列,ID為6的行源執行的正是全表掃描操作,【活動百分比】條狀圖顯示了產生了5次的direct path read等待,與我們從ASH檢視裡查詢的結果完全相符。


wps8530.tmp


因此【活動百分比】列非常重要,透過此列,我們能夠知道DB TIME的去向,例如上圖中,絕大部分的DB TIME都會花在了全表掃描階段。除了全表掃描行源,其他行源都為空,但是這並不代表其他行源沒有花取資料庫時間,而是因為這塊的內容是依據ASH取樣而來的,如果行源操作執行比較快的話,ASH就不容易捕獲到。透過【活動百分比】列,我們可以定位到最消耗資源的行源,然後可以有針對性的做最佳化,達到事半功倍的效果。


我們來看【詳細資訊】 的【並行】tab頁,這個頁面彙集了每一個並行程式完成的工作,由於ORACLE的並行採用了生產者消費者模型,首先是按照例項做的分組,然後再按照生產者和消費者把程式做了分組,我的測試例子裡,只有一個RAC節點例項,另一個節點被關閉了。


wps8531.tmp


切換到【詳細資訊】的【活動】頁,展示了從開始執行到結束執行時間跨度內,有多少程式處於活躍狀態。由於我們設定了並行度6,因此可以從頁面上看到SQL執行的後期大部分時間有6個程式處於活躍狀態。


wps8541.tmp


【詳細資訊】的【度量】頁顯示了查詢 過程中對CPU、記憶體、IO的佔用率。


wps8552.tmp


這裡我們基本上把SQL MONITORING的核心內容做了減少,這個頁面包含了大量的資訊,而且這個頁面本身具有非常大的互動性,對這個頁面你可以充分發揮你的好奇心,把你的滑鼠盡情的放在任何一個可以放的位置,盡情發掘裡面的寶藏。


5.7 透過SQL MONITORING監控索引建立過程


之所以專門寫一節透過SQL MONITORING監控索引建立過程是源於一個客戶的需求,他由於業務上的需要想要知道重建索引大概需要多久,即使不能知道準確的時間,也希望能大概知道索引建立開始後,已經完成了多少的工作,大約還有多少工作未完成 。如果是使用的11G版本 ,可以很輕鬆的透過SQL MONITORING實現這個需求。


索引的建立大體上分為兩個階段:第一,全表掃描過程 第二,排序建立索引過程。


我們這裡給出一個索引建立的例子,為了保證可以讓SQL MONITORING監控到這個語句,我使用了並行語句,當然也可以造取一個足夠大的表來確保索引建立語句執行的時間足夠長來開啟SQL MONITOR功能 。


alter index tt rebuild online parallel 6;


wps8553.tmp


索引建立開始後,我們觀察SQL MONITORING頁面的【詳細資訊】部分,【詳細資訊】頁面的最左邊列的多人圖示顯示了這是一個並行執行的語句,這裡紅色為生產者,負責掃描HASH_T1表,根據全表掃描行源(ID=8)的父操作PX BLOCK ITERATOR可以知道,PX SLAVE按照ROWID劃分工作,每個PX SLAVE負責一部分資料塊的掃描(我這裡為分割槽表,並沒有按照分割槽劃分工作),掃描後的資料寫入TQ10000 table queue,消費者PX SLAVE程式從table queue TQ10000讀取資料,這樣透過table queue TQ10000表,兩組並行程式完成了資料的傳遞。消費者PX SLAVE把接收到的資料做排序並建立索引。


wps8564.tmp


從上圖可以看出,向右的箭頭處於排序建立索引階段(行源3,4,5),全表掃描階段已經結束,正在進行排序和建立索引,根據【實際行數】列可以知道目前排序已經完成的行數是531K,而真正需要的排序量為47M,從其他行源可以知道需要排序的總量(ID=5-8的實際行數列都顯示了這個資訊)。接下來的工作就是重新整理頁面看排序的實際行數什麼時候能夠到47M了。【進度百分比】列顯示了已經完成的百分比,這個對於工作量的估算非常的有意義。有一點比較遺憾,【進度百分比】對於很多操作都不能進行顯示,很多時候【進度百分比】會在SQL執行過程中動態出現。不過對於索引建立來說,這個並不重要,根據真正的資料量和已經完成的排序量就能大概知道剩餘的工作量。


wps8574.tmp



重新整理後已經完成了28M的排序工作。



wps8575.tmp



再次重新整理,發現索引建立已經完成,因為最左邊的已經沒有向右的箭頭,而且實際行數(行源4)已經為47M,完成了所有資料的排序。我們觀察【活動百分比】這一列,整個索引建立過程中,絕大部分的時間都消耗在ID=4這個行源上,即排序和建立索引操作上,從【時間表】(Timeline)列也可以看出它的活躍時間跨度也最長。



5.8 一個例子



上面介紹了相關的SQL MONITORING的核心特性,但是它只能協助我們發現效能問題,如何解決問題它並不能幫助到我們,解決問題的過程還需要我們具備各種SQL最佳化的技能,如CBO的知識,作業系統的知識等等。



我們來透過一個小例子來進階我們對於SQL MONITORING的理解:



表的物理資訊:



hash_t1 大小 4416M



查詢語句



SQL執行時間2分鐘,由於使用了並行我們從上圖可以看到DB TIME 12.6分鐘遠大於SQL執行時間2分鐘。



wps8586.tmp



根據【活動百分比】這一列看到HASH JOIN本身佔取的資料庫時間最多,達到了51%(ASH取樣的結果),再仔細觀察執行計劃的相關內容,HASH JOIN的左邊使用了廣播的分發方式PX SEND BROADCAST,但是需要廣播的資料量非常的大,有40M,由於採用了6個併發,因此廣播之後,每一個PX程式都接收到了40M的資料量,因此總共的資料量為240M。HASH JOIN右邊的表的資料量也是40M,跟HASH JOIN左邊的表大小一樣,資料的分發方式一般包括廣播和HASH,12C新增加了replicat方式,對於HASH JOIN左邊是小表的情況一般使用廣播方式的分發,對於HASH JOIN的左邊、右邊都是大表的情況,一般使用HASH分發比較好。這裡由於每個PX消費者程式都需要完整持有HASH JOIN左邊表的資料,因此消耗的臨時段的空間也比較大,達到了4GB。



wps8587.tmp



我們來看下嘗試使用HASH 分佈效果怎麼樣:SQL執行時間從2分鐘縮減到了1.3分鐘,DB TIME也從12.6分鐘縮減到了8.3分鐘。



wps8597.tmp



檢視執行計劃發現資料分發方式已經變為PX SEND HASH,使用了HASH分發的方式,觀察【實際行數列】資料量也和表的記錄數相同,臨時表空間也從4GB大小縮減為966MB。HASH JOIN操作本身佔取的活動百分比也從51%下降為22%。



wps85A8.tmp



5.9 相關檢視



Grid Control上所有漂亮的圖表都來源於v$或DBA_檢視或許沒有必要為日常監控和調優任務經常去訪問這些v$檢視,但知道這些資訊來自哪裡仍然是很有用處的,因為這會讓自定義監控和對問題的高階診斷變得更方便,例如我所在的沃趣科技就在自動研發一套監控系統,也在考慮將SQL MONITORING這個功能增加到我們的監控產品裡,如果能瞭解到這些功能的底層檢視就對我們開發這個功能非常有好處。下面是一些要知道的關鍵檢視:



GV$SQL_MONITOR檢視包含了語句執行時的監控資料。當有多個會話在執行相同的語句時,這個檢視會有多個記錄與之對應,所以請確保使用了正確的搜尋過濾條件來獲得你所關注的SQL執行情況。例如,應該注意SID和INST_ID是不是你正在尋找的會話,對於並行執行則是PX_QCSID和PX_QCINST_ID,如果在診斷一條當前正在執行的查詢,則要檢查列status是否顯示為executing狀態。



GV$SQL_PLAN_MONITOR 檢視包含了執行計劃每一行的效能指標,這些指標會被實時監控和更新。



GV$ACTIVE_SESSION_HISTORY 檢視從ORACLE 11GR1開始包含了如SQL_PLAN_LINE_ID、SQL_PLAN_OPERATION和SQL_PLAN_OPTIONS這些列。透過查詢這些列,加上SQL_ID,就可以找到一個SQL執行計劃中最顯著的行源,而不僅僅找到最顯著的執行計劃。



5.10 控制SQL監控



對於並行執行的SQL,SQL監控會馬上對他們啟用,而不管他們執行的時間有多久。對於序列執行的SQL,SQL監控不會馬上啟用,因為SQL監控並不是用來監控通常執行速度很快的OLTP查詢的,這類查詢每秒都會被執行很多遍。然而,如果一個SQL序列查詢消耗多餘5S的CPU和IO等待時間,他將會被認為是一個長查詢,SQL監控也會對此類查詢啟用。這是自動發生的,查詢語句不需要重新執行。



可以使用提示MONITOR和NO_MONITOR來控制對一個語句的監控與否。如果你對某一個執行時間比較長的SQL不想做監控,可以使用NO_MONITOR這個HINT。需要注意有一個跟NO_MONITOR非常相像的HINT NO_MONITORING,它是與SQL MONITORING功能完全不相關的東西,透過NO_MONITORING這個HINT可以禁止對錶裡先關欄位的謂詞使用情況進行監控,這些監控資料會被放入到sys.col_usage$中。



wps85B9.tmp



5.11 使用SQL獲取SQL MONITORING的輸出



經過上面一系列的介紹,我們再來看透過SQL包獲取SQL MONITORING的輸出就變得極為簡單,這裡我不會再花費筆墨來對輸出做詳細的解釋,大部分的資訊上面我都已經講到過了。



這個主要是透過dbms_sqltune.report_sql_monitor來進行的。下面的SQL的含義是,把SQL_ID為4vnz8232nugv9的查詢,最近的SQL MONITORING的資訊以text格式列印出來:



wps85BA.tmp



wps85BB.tmp



wps85CB.tmp



wps85CC.tmp



wps85DD.tmp



dbms_sqltune.report_sql_monitor包的type除了我例子給出的text外,還可以有HTML,ACTIVE(11GR2),XML。如果你想檢視某個SQL歷史的執行統計資訊而不是最近一次的,可以透過指定SQL_EXEC_ID 引數來進行。詳細可以參考:








About Me

...............................................................................................................................

● 本文整理自網路

● 本文在itpub(http://blog.itpub.net/26736162)、部落格園(cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文部落格園地址:cnblogs.com/lhrbest

● 本文pdf版及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● QQ群:230161599     微信群:私聊

● 聯絡我請加QQ好友(646634621),註明新增緣由

● 於 2017-07-01 09:00 ~ 2017-07-31 22:00 在魔都完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

...............................................................................................................................

拿起手機使用微信客戶端掃描下邊的左邊圖片來關注小麥苗的微信公眾號:xiaomaimiaolhr,掃描右邊的二維碼加入小麥苗的QQ群,學習最實用的資料庫技術。

【SQL】Oracle SQL monitor
DBA筆試面試講解
歡迎與我聯絡

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28211342/viewspace-2150646/,如需轉載,請註明出處,否則將追究法律責任。

相關文章