創(chuàng)新互聯(lián)公司主要業(yè)務(wù)有網(wǎng)站營銷策劃、做網(wǎng)站、網(wǎng)站制作、微信公眾號開發(fā)、小程序制作、H5頁面制作、程序開發(fā)等業(yè)務(wù)。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當(dāng)客戶,還把客戶視為我們的合作伙伴,在開展業(yè)務(wù)的過程中,公司還積累了豐富的行業(yè)經(jīng)驗(yàn)、成都全網(wǎng)營銷資源和合作伙伴關(guān)系資源,并逐漸建立起規(guī)范的客戶服務(wù)和保障體系。
Oracle高資源消耗SQL語句定位
http://www.ecdoer.com/post/oracle-highcost-sql-locate.html
Oracle SQL語句資源消耗監(jiān)控最常用的系統(tǒng)視圖有v$sql、v$sqlarea、v$sqltext和v$session。本文我們先了解這些視圖的作用與區(qū)別,然后了解如何定位高資源消耗SQL語句,最后再了解一下各視圖字段具體含義。 相關(guān)系統(tǒng)視圖功能與區(qū)別
v$sql和v$sqlarea基本相同,記錄了共享SQL區(qū)(share
pool)中SQL統(tǒng)計(jì)信息,如內(nèi)存消耗、IO(物理磁盤讀和邏輯內(nèi)存讀)、排序操作、哈希ID等數(shù)據(jù)。不同之處在于v$sql為每一條SQL保留一個條目,而v$sqlarea中根據(jù)sql_text(需要注意,該處存儲的為當(dāng)前SQL指針的前1000個字符,也就是說這里記錄的SQL可能是不完整的?。┻M(jìn)行g(shù)roup
by,統(tǒng)計(jì)列進(jìn)行sum(),通過version_count計(jì)算子指針的個數(shù)。
然而,文本(sql_text)相同的SQL語句在數(shù)據(jù)庫中意義可能完全不同。比如數(shù)據(jù)庫中存在兩個用戶User1和User2,這兩個用戶各擁有一張數(shù)據(jù)表EMP。那么當(dāng)兩個用戶發(fā)出查詢select
count(*) from
emp;時各自訪問自己SCHEMA中的表EMP,而兩者表內(nèi)容不同所以其資源消耗肯定也不同。此時,在v$sql中會有這兩條完全一樣的SQL各自的統(tǒng)計(jì)信息,而在v$sqlarea中sql_text相同的2個指針會合并起來,執(zhí)行次數(shù)、DISK_READS、BUFFER_GETS等統(tǒng)計(jì)信息都會累加(sum),version_count會顯示為2,這就是v$sqlarea的聚合作用。
v$sqltext中沒有統(tǒng)計(jì)信息,然而卻存儲著完整的SQL語句及其哈希ID等。
對于這三者,我們可以使用視圖v$fixed_view_definition來查看視圖的源表,如下:
SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQL';
SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQLAREA';
SELECT view_definition FROM v$fixed_view_definition WHERE view_name='GV$SQLTEXT';
注:視圖名為V$SQL但該視圖的源又是GV$SQL,所以直接使用GV$SQL,其他兩個也如此。
通過以上3條語句可以發(fā)現(xiàn),V$SQL數(shù)據(jù)來源X$KGLCURSOR_CHILD,其實(shí)數(shù)據(jù)還是來源于X$KGLOB;而V$SQLAREA數(shù)據(jù)來源X$KGLCURSOR_CHILD_SQLID本質(zhì)是對X$KGLCURSOR_CHILD按照sql_id等字段分組匯總后的結(jié)果;V$SQLTEXT數(shù)據(jù)來源X$KGLNA。
v$session主要用來確定會話相關(guān)信息,如通過SID和SERIAL#來唯一確定一個session(SID可能會重復(fù))、會話擁有者用戶名USERNAME、會話狀態(tài)(active:正在執(zhí)行SQL語句、inactive:等待操作、killed:被殺死)、會話由哪個客戶端發(fā)起(MACHINE、TERMINAL)、正在執(zhí)行什么SQL(通過SQL_ADDRESS、SQL_HASH_VALUE、SQL_ID、SQL_CHILD_NUMBER確定,有這些再借助v$sqltext就能知道)、甚至上一次執(zhí)行的SQL是什么(通過PREV_SQL_ADDRESS等確定)、鎖等待相關(guān)信息(如所在表、文件、塊、被鎖行)等。
高資源消耗SQL查找定位
1)查看讀硬盤多或占用內(nèi)存可能多的SQL:
select sql_text, disk_reads, buffer_gets, parsing_schema_name, executions
from v$sqlarea
order by disk_reads desc;
說明:單純從V$sqlarea中是無法查出每個SQL消耗的內(nèi)存量的,但我們可以借助磁盤讀次數(shù)間接反映可能的消耗內(nèi)存量較大的SQL語句,然后再借助執(zhí)行計(jì)劃(如v$sql_plan視圖)具體查看。
利用系統(tǒng)視圖v$sqlarea,其中disk_reads是磁盤讀次數(shù),也是主要字段,剩余字段均為參考字段。其中,buffer_gets是內(nèi)存讀次數(shù),parsing_schema_name是首次編譯者模式名(一般與user名相同),executions是語句執(zhí)行次數(shù)。
需要注意的是,v$sqlarea中sql_text可能不完整,若需要完整的則需要借助hash_value或sql_id結(jié)合v$sqltext來查看分析。
2)查看執(zhí)行次數(shù)多的SQL
select sql_text, executions, parsing_schema_name
from v$sqlarea
order by executions desc;
3)查看排序多的SQL
select sql_text, sorts, parsing_schema_name
from v$sqlarea
order by sorts desc;
該處還應(yīng)涉及Library Cache命中率、內(nèi)存命中率等內(nèi)容,暫不總結(jié),見轉(zhuǎn)載內(nèi)容“Oracle調(diào)優(yōu)相關(guān)的各種命中率、使用率匯總”。
相關(guān)視圖重要字段
v$sqlarea
v$sql和v$sqlarea基本類似,而v$sqlarea更常用,故僅對v$sqlarea常用字段進(jìn)行說明,如下(個人參考Oracle官方文檔翻譯的,因是最新版本,所以會跟網(wǎng)絡(luò)上的有些出入):
-
SQL_TEXT:SQL語句的前1000個字符;
-
SQL_FULLTEXT:SQL語句的所有字符;
-
SQL_ID:緩存在高速緩沖區(qū)(library cache)中的SQL父游標(biāo)的唯一標(biāo)識ID(注,類似于hash_value,不過hash_value是4bytes而sql_id是8bytes,sql_id更精確后期可能會替代hash_value);
-
SHARABLE_MEM:SQL語句及其子游標(biāo)占用的共享內(nèi)存大小;
-
PERSISTENT_MEM:打開SQL語句的生命周期內(nèi)所占用的固定內(nèi)存大?。ò佑螛?biāo));
-
RUNTIME_MEM:游標(biāo)執(zhí)行期間所占用的固定內(nèi)存大?。?/strong>
-
SORTS:語句執(zhí)行導(dǎo)致的排序次數(shù);
-
VERSION_COUNT:在緩存中以該語句為父語句的子游標(biāo)總數(shù);
-
LOADED_VERSIONS:緩存中載入了這條語句上下文堆(KGL heap 6)的子游標(biāo)數(shù);
-
OPEN_VERSIONS:父游標(biāo)下打開的子游標(biāo)個數(shù);
-
USERS_OPENING:打開子游標(biāo)的用戶個數(shù);
-
FETCHES:SQL語句的fetch數(shù);
-
EXECUTIONS:包含所有子游標(biāo)在內(nèi)該SQL語句共執(zhí)行次數(shù);
-
USERS_EXECUTING:執(zhí)行過該語句所有子游標(biāo)的用戶總數(shù);
-
LOADS:語句被載入的總次數(shù);
-
FIRST_LOAD_TIME:父游標(biāo)被首次載入(編譯)的時間;
-
PARSE_CALLS:父游標(biāo)下所有子游標(biāo)解析調(diào)用次數(shù);
-
DISK_READS:該語句通過所有子游標(biāo)導(dǎo)致的讀磁盤次數(shù);
-
DIRECT_WRITES:該語句通過所有子游標(biāo)導(dǎo)致的直接寫入次數(shù);
-
BUFFER_GETS:該語句通過所有子游標(biāo)導(dǎo)致的讀緩存次數(shù);
-
APPLICATION_WAIT_TIME:應(yīng)用等待時間;
-
USER_IO_WAIT_TIME:用戶I/O等待時間;
-
PLSQL_EXEC_TIME:PLSQL執(zhí)行時間;
-
ROWS_PROCESSED:該SQL語句處理的總行數(shù);
-
OPTIMIZER_COST:此查詢優(yōu)化給出的成本數(shù);
-
PARSING_USER_ID:第一次解析該父語句的用戶ID;
-
PARSING_SCHEMA_ID:第一次解析該語句SCHEMA的ID;
-
PARSING_SCHEMA_NAME:解析該語句的SCHEMA的NAME;
-
KEPT_VERSIONS:指出是否當(dāng)前子游標(biāo)被使用DBMS_SHARED_POOL包標(biāo)記為常駐內(nèi)存;
-
ADDRESS:當(dāng)前游標(biāo)父句柄(唯一指向該游標(biāo)的一種地址編號);
-
HASH_VALUE:該語句在library cache中hash值;
-
PLAN_HASH_VALUE:執(zhí)行計(jì)劃的hash值,可依此確定兩個執(zhí)行計(jì)劃是否相同(取代每行每字符進(jìn)行比較的方式);
-
CPU_TIME:該語句解析、執(zhí)行和fetch(取值)所消耗的CPU時間;
-
ELAPSED_TIME:該語句解析、執(zhí)行和fetch(取值)所經(jīng)過的時間;
-
LAST_ACTIVE_TIME:查詢計(jì)劃最后一次執(zhí)行的時間;
-
LOCKED_TOTAL:所有子游標(biāo)被鎖的次數(shù);'
v$sqltext
-
ADDRESS:當(dāng)前游標(biāo)父句柄(唯一指向該游標(biāo)的一種地址編號);
-
HASH_VALUE:該游標(biāo)(子游標(biāo))在library cache中唯一hash值;
-
SQL_ID:緩存游標(biāo)中該SQL的一個唯一標(biāo)識值;
-
COMMAND_TYPE:SQL語句類型,如select、insert、update等;
-
PIECE:排序SQL文本的碎片數(shù);
-
SQL_TEXT:包含一個完整SQL中的某一小塊SQL文本字符(要完整的SQL語句需要把這些碎片組合起來);
v$session
-
SADDR:session地址;
-
SID:session標(biāo)識值,常跟serial#聯(lián)合唯一確定一個session(在殺進(jìn)程時,有時SID會重用,造成誤殺。而serial會增加但不會重復(fù),sid
在同一個instance的當(dāng)前session中是一個unique key,而sid
,serial#則是在整個instance生命期內(nèi)的所有session中是unique key);
-
SERIAL#:會話序列號,用于在一個會話結(jié)束而另一個會話重用這該會話的SID時,唯一確定一個會話;
-
AUDSID:審計(jì)會話ID,可以通過audsid查詢當(dāng)前session的sid,select sid from v$session where audsid=userenv('sessionid');
-
PADDR:進(jìn)程地址,關(guān)聯(lián)v$process的addr字段,通過這個可以查詢到進(jìn)程對應(yīng)的session;
-
USER#:同于dba_users中的user_id,Oracle內(nèi)部進(jìn)程user#為0;
-
USERNAME:會話擁有者用戶名,等于dba_users中的username,Oracle內(nèi)部進(jìn)程的username為空;
-
COMMAND:正在執(zhí)行的SQL語句類型,如1為create table、3為select等;
-
OWNERID:如果該列值為2147483644則值無效,否則值用于會話遷移、并行等;
-
TADDR:Address of transaction state object;
-
LOCKWAIT:標(biāo)識當(dāng)前查詢是否處于鎖等待狀態(tài),為空則表示無等待;
-
STATUS:標(biāo)識session狀態(tài),Active正執(zhí)行SQL語句,inactive等待操作,killed被標(biāo)注為殺死;
-
SERVER:服務(wù)器類型,DEDICATED專用、SHARED共享等;
-
SCHEMA#:SCHEMA標(biāo)識ID值,Oracle內(nèi)部進(jìn)程的schema#為0;
-
SCHEMANAME:SCHEMA用戶名,Oracle內(nèi)部進(jìn)程的為sys;
-
OSUSER:客戶端操作系統(tǒng)用戶名;
-
PROCESS:客戶端操作系統(tǒng)進(jìn)程ID;
-
MACHINE:操作系統(tǒng)機(jī)器名;
-
TERMINAL:操作系統(tǒng)終端名;
-
PROGRAM:操作系統(tǒng)應(yīng)用程序名,如EXE或sqlplus.exe;
-
TYPE:會話類型,如BACKGROUND或USER;
-
SQL_ADDRESS:和SQL_HASH_VALUE一起使用標(biāo)識正在執(zhí)行的SQL語句;
-
SQL_HASH_VALUE:和SQL_ADDRESS一起使用標(biāo)識正在執(zhí)行的SQL語句;
-
SQL_ID:正在執(zhí)行的SQL語句的標(biāo)識ID;
-
SQL_CHILD_NUMBER:正在執(zhí)行的SQL語句的子ID;
-
FIXED_TABLE_SEQUENCE:當(dāng)session完成一個user
call后就會增加的一個數(shù)值,也就是說,如果session掛起,它就不會增加。因此可以根據(jù)這個字段來監(jiān)控某個時間點(diǎn)以來的session性能情況。例如,一個小時前某個session的此字段數(shù)值為10000,而現(xiàn)在是20000,則表明一個小時內(nèi)其user
call較頻繁,可以重點(diǎn)關(guān)注此session的performance statistics。
-
ROW_WAIT_OBJ#:被鎖定行所在table的object_id,和dba_object中的object_id關(guān)聯(lián)可以得到被鎖定的table name;
-
ROW_WAIT_FILE#:被鎖定行所在的datafile id,和v$datafile中的file#關(guān)聯(lián)可以得到datafile name;
-
ROW_WAIT_BLOCK#:被鎖定的塊ID;
-
ROW_WAIT_ROW#:被鎖定的當(dāng)前行;
-
LOGON_TIME:登錄時間;
分享標(biāo)題:Oracle高資源消耗SQL語句定位
標(biāo)題來源:
http://weahome.cn/article/gicgsj.html