溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Oracle高資源消耗SQL語(yǔ)句定位

發(fā)布時(shí)間:2020-08-15 00:03:44 來(lái)源:ITPUB博客 閱讀:272 作者:不一樣的天空w 欄目:關(guān)系型數(shù)據(jù)庫(kù)

Oracle高資源消耗SQL語(yǔ)句定位

http://www.ecdoer.com/post/oracle-highcost-sql-locate.html



Oracle SQL語(yǔ)句資源消耗監(jiān)控最常用的系統(tǒng)視圖有v$sql、v$sqlarea、v$sqltext和v$session。本文我們先了解這些視圖的作用與區(qū)別,然后了解如何定位高資源消耗SQL語(yǔ)句,最后再了解一下各視圖字段具體含義。


相關(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保留一個(gè)條目,而v$sqlarea中根據(jù)sql_text(需要注意,該處存儲(chǔ)的為當(dāng)前SQL指針的前1000個(gè)字符,也就是說(shuō)這里記錄的SQL可能是不完整的?。┻M(jìn)行g(shù)roup by,統(tǒng)計(jì)列進(jìn)行sum(),通過(guò)version_count計(jì)算子指針的個(gè)數(shù)。

然而,文本(sql_text)相同的SQL語(yǔ)句在數(shù)據(jù)庫(kù)中意義可能完全不同。比如數(shù)據(jù)庫(kù)中存在兩個(gè)用戶User1和User2,這兩個(gè)用戶各擁有一張數(shù)據(jù)表EMP。那么當(dāng)兩個(gè)用戶發(fā)出查詢select count(*) from emp;時(shí)各自訪問(wèn)自己SCHEMA中的表EMP,而兩者表內(nèi)容不同所以其資源消耗肯定也不同。此時(shí),在v$sql中會(huì)有這兩條完全一樣的SQL各自的統(tǒng)計(jì)信息,而在v$sqlarea中sql_text相同的2個(gè)指針會(huì)合并起來(lái),執(zhí)行次數(shù)、DISK_READS、BUFFER_GETS等統(tǒng)計(jì)信息都會(huì)累加(sum),version_count會(huì)顯示為2,這就是v$sqlarea的聚合作用。

v$sqltext中沒有統(tǒng)計(jì)信息,然而卻存儲(chǔ)著完整的SQL語(yǔ)句及其哈希ID等。

對(duì)于這三者,我們可以使用視圖v$fixed_view_definition來(lái)查看視圖的源表,如下:

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,其他兩個(gè)也如此。

通過(guò)以上3條語(yǔ)句可以發(fā)現(xiàn),V$SQL數(shù)據(jù)來(lái)源X$KGLCURSOR_CHILD,其實(shí)數(shù)據(jù)還是來(lái)源于X$KGLOB;而V$SQLAREA數(shù)據(jù)來(lái)源X$KGLCURSOR_CHILD_SQLID本質(zhì)是對(duì)X$KGLCURSOR_CHILD按照sql_id等字段分組匯總后的結(jié)果;V$SQLTEXT數(shù)據(jù)來(lái)源X$KGLNA。

v$session主要用來(lái)確定會(huì)話相關(guān)信息,如通過(guò)SID和SERIAL#來(lái)唯一確定一個(gè)session(SID可能會(huì)重復(fù))、會(huì)話擁有者用戶名USERNAME、會(huì)話狀態(tài)(active:正在執(zhí)行SQL語(yǔ)句、inactive:等待操作、killed:被殺死)、會(huì)話由哪個(gè)客戶端發(fā)起(MACHINE、TERMINAL)、正在執(zhí)行什么SQL(通過(guò)SQL_ADDRESS、SQL_HASH_VALUE、SQL_ID、SQL_CHILD_NUMBER確定,有這些再借助v$sqltext就能知道)、甚至上一次執(zhí)行的SQL是什么(通過(guò)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;

說(shuō)明:?jiǎn)渭儚腣$sqlarea中是無(wú)法查出每個(gè)SQL消耗的內(nèi)存量的,但我們可以借助磁盤讀次數(shù)間接反映可能的消耗內(nèi)存量較大的SQL語(yǔ)句,然后再借助執(zhí)行計(jì)劃(如v$sql_plan視圖)具體查看。

利用系統(tǒng)視圖v$sqlarea,其中disk_reads是磁盤讀次數(shù),也是主要字段,剩余字段均為參考字段。其中,buffer_gets是內(nèi)存讀次數(shù),parsing_schema_name是首次編譯者模式名(一般與user名相同),executions是語(yǔ)句執(zhí)行次數(shù)。

需要注意的是,v$sqlarea中sql_text可能不完整,若需要完整的則需要借助hash_value或sql_id結(jié)合v$sqltext來(lái)查看分析。

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更常用,故僅對(duì)v$sqlarea常用字段進(jìn)行說(shuō)明,如下(個(gè)人參考Oracle官方文檔翻譯的,因是最新版本,所以會(huì)跟網(wǎng)絡(luò)上的有些出入):

  • SQL_TEXT:SQL語(yǔ)句的前1000個(gè)字符;
  • SQL_FULLTEXT:SQL語(yǔ)句的所有字符;
  • SQL_ID:緩存在高速緩沖區(qū)(library cache)中的SQL父游標(biāo)的唯一標(biāo)識(shí)ID(注,類似于hash_value,不過(guò)hash_value是4bytes而sql_id是8bytes,sql_id更精確后期可能會(huì)替代hash_value);
  • SHARABLE_MEM:SQL語(yǔ)句及其子游標(biāo)占用的共享內(nèi)存大?。?/strong>
  • PERSISTENT_MEM:打開SQL語(yǔ)句的生命周期內(nèi)所占用的固定內(nèi)存大?。ò佑螛?biāo));
  • RUNTIME_MEM:游標(biāo)執(zhí)行期間所占用的固定內(nèi)存大??;
  • SORTS:語(yǔ)句執(zhí)行導(dǎo)致的排序次數(shù);
  • VERSION_COUNT:在緩存中以該語(yǔ)句為父語(yǔ)句的子游標(biāo)總數(shù);
  • LOADED_VERSIONS:緩存中載入了這條語(yǔ)句上下文堆(KGL heap 6)的子游標(biāo)數(shù);
  • OPEN_VERSIONS:父游標(biāo)下打開的子游標(biāo)個(gè)數(shù);
  • USERS_OPENING:打開子游標(biāo)的用戶個(gè)數(shù);
  • FETCHES:SQL語(yǔ)句的fetch數(shù);
  • EXECUTIONS:包含所有子游標(biāo)在內(nèi)該SQL語(yǔ)句共執(zhí)行次數(shù);
  • USERS_EXECUTING:執(zhí)行過(guò)該語(yǔ)句所有子游標(biāo)的用戶總數(shù);
  • LOADS:語(yǔ)句被載入的總次數(shù);
  • FIRST_LOAD_TIME:父游標(biāo)被首次載入(編譯)的時(shí)間;
  • PARSE_CALLS:父游標(biāo)下所有子游標(biāo)解析調(diào)用次數(shù);
  • DISK_READS:該語(yǔ)句通過(guò)所有子游標(biāo)導(dǎo)致的讀磁盤次數(shù);
  • DIRECT_WRITES:該語(yǔ)句通過(guò)所有子游標(biāo)導(dǎo)致的直接寫入次數(shù);
  • BUFFER_GETS:該語(yǔ)句通過(guò)所有子游標(biāo)導(dǎo)致的讀緩存次數(shù);
  • APPLICATION_WAIT_TIME:應(yīng)用等待時(shí)間;
  • USER_IO_WAIT_TIME:用戶I/O等待時(shí)間;
  • PLSQL_EXEC_TIME:PLSQL執(zhí)行時(shí)間;
  • ROWS_PROCESSED:該SQL語(yǔ)句處理的總行數(shù);
  • OPTIMIZER_COST:此查詢優(yōu)化給出的成本數(shù);
  • PARSING_USER_ID:第一次解析該父語(yǔ)句的用戶ID;
  • PARSING_SCHEMA_ID:第一次解析該語(yǔ)句SCHEMA的ID;
  • PARSING_SCHEMA_NAME:解析該語(yǔ)句的SCHEMA的NAME;
  • KEPT_VERSIONS:指出是否當(dāng)前子游標(biāo)被使用DBMS_SHARED_POOL包標(biāo)記為常駐內(nèi)存;
  • ADDRESS:當(dāng)前游標(biāo)父句柄(唯一指向該游標(biāo)的一種地址編號(hào));
  • HASH_VALUE:該語(yǔ)句在library cache中hash值;
  • PLAN_HASH_VALUE:執(zhí)行計(jì)劃的hash值,可依此確定兩個(gè)執(zhí)行計(jì)劃是否相同(取代每行每字符進(jìn)行比較的方式);
  • CPU_TIME:該語(yǔ)句解析、執(zhí)行和fetch(取值)所消耗的CPU時(shí)間;
  • ELAPSED_TIME:該語(yǔ)句解析、執(zhí)行和fetch(取值)所經(jīng)過(guò)的時(shí)間;
  • LAST_ACTIVE_TIME:查詢計(jì)劃最后一次執(zhí)行的時(shí)間;
  • LOCKED_TOTAL:所有子游標(biāo)被鎖的次數(shù);'


v$sqltext

  • ADDRESS:當(dāng)前游標(biāo)父句柄(唯一指向該游標(biāo)的一種地址編號(hào));
  • HASH_VALUE:該游標(biāo)(子游標(biāo))在library cache中唯一hash值;
  • SQL_ID:緩存游標(biāo)中該SQL的一個(gè)唯一標(biāo)識(shí)值;
  • COMMAND_TYPE:SQL語(yǔ)句類型,如select、insert、update等;
  • PIECE:排序SQL文本的碎片數(shù);
  • SQL_TEXT:包含一個(gè)完整SQL中的某一小塊SQL文本字符(要完整的SQL語(yǔ)句需要把這些碎片組合起來(lái));


v$session

  • SADDR:session地址;
  • SID:session標(biāo)識(shí)值,常跟serial#聯(lián)合唯一確定一個(gè)session(在殺進(jìn)程時(shí),有時(shí)SID會(huì)重用,造成誤殺。而serial會(huì)增加但不會(huì)重復(fù),sid 在同一個(gè)instance的當(dāng)前session中是一個(gè)unique key,而sid ,serial#則是在整個(gè)instance生命期內(nèi)的所有session中是unique key);
  • SERIAL#:會(huì)話序列號(hào),用于在一個(gè)會(huì)話結(jié)束而另一個(gè)會(huì)話重用這該會(huì)話的SID時(shí),唯一確定一個(gè)會(huì)話;
  • AUDSID:審計(jì)會(huì)話ID,可以通過(guò)audsid查詢當(dāng)前session的sid,select sid from v$session where audsid=userenv('sessionid');
  • PADDR:進(jìn)程地址,關(guān)聯(lián)v$process的addr字段,通過(guò)這個(gè)可以查詢到進(jìn)程對(duì)應(yīng)的session;
  • USER#:同于dba_users中的user_id,Oracle內(nèi)部進(jìn)程user#為0;
  • USERNAME:會(huì)話擁有者用戶名,等于dba_users中的username,Oracle內(nèi)部進(jìn)程的username為空;
  • COMMAND:正在執(zhí)行的SQL語(yǔ)句類型,如1為create table、3為select等;
  • OWNERID:如果該列值為2147483644則值無(wú)效,否則值用于會(huì)話遷移、并行等;
  • TADDR:Address of transaction state object;
  • LOCKWAIT:標(biāo)識(shí)當(dāng)前查詢是否處于鎖等待狀態(tài),為空則表示無(wú)等待;
  • STATUS:標(biāo)識(shí)session狀態(tài),Active正執(zhí)行SQL語(yǔ)句,inactive等待操作,killed被標(biāo)注為殺死;
  • SERVER:服務(wù)器類型,DEDICATED專用、SHARED共享等;
  • SCHEMA#:SCHEMA標(biāo)識(shí)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:會(huì)話類型,如BACKGROUND或USER;
  • SQL_ADDRESS:和SQL_HASH_VALUE一起使用標(biāo)識(shí)正在執(zhí)行的SQL語(yǔ)句;
  • SQL_HASH_VALUE:和SQL_ADDRESS一起使用標(biāo)識(shí)正在執(zhí)行的SQL語(yǔ)句;
  • SQL_ID:正在執(zhí)行的SQL語(yǔ)句的標(biāo)識(shí)ID;
  • SQL_CHILD_NUMBER:正在執(zhí)行的SQL語(yǔ)句的子ID;
  • FIXED_TABLE_SEQUENCE:當(dāng)session完成一個(gè)user call后就會(huì)增加的一個(gè)數(shù)值,也就是說(shuō),如果session掛起,它就不會(huì)增加。因此可以根據(jù)這個(gè)字段來(lái)監(jiān)控某個(gè)時(shí)間點(diǎn)以來(lái)的session性能情況。例如,一個(gè)小時(shí)前某個(gè)session的此字段數(shù)值為10000,而現(xiàn)在是20000,則表明一個(gè)小時(shí)內(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:登錄時(shí)間;
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI