Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 91在线观看视频,一区二区在线视频观看,日韩一区二区三区电影

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          DBA常用sql之Oracle

          DBA常用sql之Oracle

          看重復(fù)索引

          WITH indexes AS (
          SELECT
              i.owner,
              i.index_name,
              i.table_name,
              listagg(c.column_name, ', ') WITHIN GROUP (
          ORDER BY
              c.column_position) AS columns
          FROM
              dba_indexes i
          JOIN dba_ind_columns c ON
              i.index_name=c.index_name
          GROUP BY
              i.owner,
              i.table_name,
              i.index_name,
              i.leaf_blocks )
          SELECT
              i.OWNER ,
              i.table_name,
              i.index_name AS "Deletion candidate index",
              i.columns AS "Deletion candidate columns",
              j.index_name AS "Existing index",
              j.columns AS "Existing columns"
          FROM
              indexes i
          JOIN indexes j ON
              i.table_name=j.table_name
              AND j.columns LIKE i.columns || ',%'

          用戶命中率

          SET LINESIZE 500
          COLUMN "Hit Ratio %" FORMAT 999.99
          
          SELECT a.username "Username",
                 b.consistent_gets "Consistent Gets",
                 b.block_gets "DB Block Gets",
                 b.physical_reads "Physical Reads",
                 Round(100* (b.consistent_gets + b.block_gets - b.physical_reads) /
                 (b.consistent_gets + b.block_gets),2) "Hit Ratio %"
          FROM   v$session a,
                 v$sess_io b
          WHERE  a.sid=b.sid
          AND    (b.consistent_gets + b.block_gets) > 0
          AND    a.username IS NOT NULL;

          查詢碎片程度高(實(shí)際使用率小于30%)的表

          可以收縮的表?xiàng)l件為什么block>100,因?yàn)橐恍┖苄〉谋恚挥袔仔袛?shù)據(jù)實(shí)際大小很小,但是block一次性分配就是5個(gè)(11g開始默認(rèn)一次性分配1M的block大小了,見create table storged的NEXT參數(shù)),5個(gè)block相對(duì)于幾行小表數(shù)據(jù)來說就相差太大了。

          算法中/0.9是因?yàn)閴K的pfree一般為10%,所以一個(gè)塊最多只用了90%,而且一行數(shù)據(jù)大于8KB時(shí)容易產(chǎn)生行鏈接,把一行分片存儲(chǔ),一樣的一個(gè)塊連90%都用不滿 ,AVGROWLEN還是比較準(zhǔn)的,比如個(gè)人實(shí)驗(yàn)情況一表6個(gè)字段,一個(gè)number,其他5個(gè)都是char(100)但是實(shí)際數(shù)據(jù)都是’1111111’7位,AVGROWLEN顯示依然為513 。

          SELECT TABLE_NAME,
                 (BLOCKS * 8192 / 1024 / 1024) "理論大小M",
                 (NUM_ROWS * AVG_ROW_LEN / 1024 / 1024 / 0.9) "實(shí)際大小M",
                 round((NUM_ROWS * AVG_ROW_LEN / 1024 / 1024 / 0.9) /
                       (BLOCKS * 8192 / 1024 / 1024),
                       3) * 100 || '%' "實(shí)際使用率%"
            FROM DBA_TABLES
           where blocks > 100
             and owner='TXPROD'
             and (NUM_ROWS * AVG_ROW_LEN / 1024 / 1024 / 0.9) /
                 (BLOCKS * 8192 / 1024 / 1024) < 0.3
           order by (NUM_ROWS * AVG_ROW_LEN / 1024 / 1024 / 0.9) /
                    (BLOCKS * 8192 / 1024 / 1024) desc

          查詢索引碎片的比例

          索引刪除行數(shù)除以索引總行數(shù)的百分比>30%即認(rèn)為索引碎片大,也就是需要重建的索引

          select name,
                 del_lf_rows,
                 lf_rows,
                 round(del_lf_rows / decode(lf_rows, 0, 1, lf_rows) * 100, 0) || '%' frag_pct
            from index_stats
           where round(del_lf_rows / decode(lf_rows, 0, 1, lf_rows) * 100, 0) > 30;

          集群因子clustering_factor高的表

          集群因子越接近塊數(shù)越好,接近行數(shù)則說明索引列的列值相等的行分布極度散列,可能不走索引掃描而走全表掃描 :

          方法一

          /* Formatted on 2019/11/6 10:02:07 (QP5 v5.326) */
          SELECT tab.table_name,
                 tab.blocks,
                 tab.num_rows,
                 ind.index_name,
                 ind.clustering_factor,
                      ROUND (
                            NVL (ind.clustering_factor, 1)
                          / DECODE (tab.num_rows, 0, 1, tab.num_rows),
                          3)
                    * 100
                 || '%'
                     "集群因子接近行數(shù)"
            FROM user_tables tab, user_indexes ind
           WHERE     tab.table_name=ind.table_name
                 AND tab.owner='TXPROD'
                 AND tab.blocks > 100
                 AND   NVL (ind.clustering_factor, 1)
                     / DECODE (tab.num_rows, 0, 1, tab.num_rows) BETWEEN 0.35
                                                                     AND 3

          方法二

          /* Formatted on 2019/11/6 10:03:16 (QP5 v5.326) */
          SELECT tab.owner,
                 tab.table_name,
                 tab.blocks,
                 tab.num_rows,
                 ind.index_name,
                 ind.clustering_factor,
                      ROUND (
                            NVL (ind.clustering_factor, 1)
                          / DECODE (tab.num_rows, 0, 1, tab.num_rows),
                          3)
                    * 100
                 || '%'
                     "集群因子接近行數(shù)"
            FROM dba_tables tab, dba_indexes ind
           WHERE     tab.table_name=ind.table_name
                 AND tab.OWNER=ind.OWNER
                 AND tab.owner NOT IN ('SYS',
                                       'SYSTEM',
                                       'WMSYS',
                                       'DBSNMP',
                                       'CTXSYS',
                                       'XDB',
                                       'ORDDATA',
                                       'SYSMAN',
                                       'CATALOG',
                                       'APEX_030200',
                                       'MDSYS',
                                       'OLAPSYS',
                                       'EXFSYS')
                 AND tab.blocks > 100
                 AND   NVL (ind.clustering_factor, 1)
                     / DECODE (tab.num_rows, 0, 1, tab.num_rows) BETWEEN 0.35
                                                                     AND 3

          根據(jù)sid查spid或根據(jù)spid查sid

          SELECT s.sid,
                 s.serial#,
                 p.spid,
                 s.terminal,
                 s.LOGON_TIME,
                 s.status,
                 s.PROGRAM,
                 s.CLIENT_IDENTIFIER,
                 s.machine,
                 s.action,
                 s.MODULE,
                 s.PROCESS     "客戶端機(jī)器進(jìn)程號(hào)",
                 s.osuser
            FROM v$session s, v$process p
           WHERE s.paddr=p.addr AND s.sid=XX OR p.spid=YY

          根據(jù)sid查看具體的sql語句,不要加條件v$session.status=’ ACTIVE’,比如toad對(duì)同一數(shù)據(jù)庫(kù)開兩個(gè)連接會(huì)話,都執(zhí)行了一些語句,其中一個(gè)窗口查詢select * from v$session時(shí)會(huì)發(fā)現(xiàn)另一個(gè)窗口在v$session.status是INACTIVE,并不代表另一個(gè)窗口沒有執(zhí)行過sql語句,而當(dāng)前窗口是active狀態(tài),對(duì)應(yīng)的sql_id對(duì)應(yīng)的語句就是select * from v$session而不是之前執(zhí)行過的sql語句,ACTIVE表示當(dāng)前正在執(zhí)行sql。

          一個(gè)sid可能執(zhí)行過很多個(gè)sql,所以有時(shí)需要的sql通過如下查不到是正常的,比如查詢到某死鎖源sid,通過如下查詢可能只是個(gè)select語句,而真正引起死鎖的sql卻查不到,是因?yàn)榭赡苓@個(gè)sid持續(xù)了很長(zhǎng)時(shí)間,這個(gè)sid之前執(zhí)行的一些sql在v$sql可能已經(jīng)被清除了。

          方法一

          /* Formatted on 2019/11/6 10:04:20 (QP5 v5.326) */
            SELECT username,
                   sid,
                   SERIAL#,
                   LOGON_TIME,
                   status,
                   PROGRAM,
                   CLIENT_IDENTIFIER,
                   machine,
                   action,
                   PROCESS     "客戶端機(jī)器進(jìn)程號(hào)",
                   osuser,
                   sql_text
              FROM v$session a, v$sqltext_with_newlines b
             WHERE     DECODE (a.sql_hash_value, 0, prev_hash_value, sql_hash_value)=     b.hash_value
                   AND a.sid=&sid
          ORDER BY piece;

          方法二

          /* Formatted on 2019/11/6 10:04:35 (QP5 v5.326) */
          SELECT username,
                 sid,
                 SERIAL#,
                 LOGON_TIME,
                 status,
                 sql_fulltext,
                 PROGRAM,
                 CLIENT_IDENTIFIER,
                 machine,
                 a.action,
                 PROCESS     "客戶端機(jī)器進(jìn)程號(hào)",
                 osuser
            FROM v$session a, v$sql b
           WHERE     DECODE (a.sql_hash_value, 0, prev_hash_value, sql_hash_value)=   b.hash_value
                 AND a.sid=&sid

          如果上面語句執(zhí)行太慢,則按如下兩步

          /* Formatted on 2019/11/6 10:05:18 (QP5 v5.326) */
          SELECT sql_hash_value,
                 prev_hash_value,
                 username,
                 sid,
                 SERIAL#,
                 LOGON_TIME,
                 status,
                 PROGRAM,
                 CLIENT_IDENTIFIER,
                 machine,
                 action,
                 PROCESS     "客戶端機(jī)器進(jìn)程號(hào)",
                 osuser
            FROM v$session
           WHERE sid=&sid;
          
          SELECT sql_fulltext
            FROM v$sql
           WHERE hash_value=XX;

          --XX為上面 sqlhashvalue,如果 sqlhashvalue為0,則XX為上面 prevhashvalue

          根據(jù)spid查詢具體的sql語句(不要加條件v$session.status=’ ACTIVE’,比如toad對(duì)同一數(shù)據(jù)庫(kù)開兩個(gè)連接會(huì)話,都執(zhí)行了一些語句,其中一個(gè)窗口查詢select * from v$session時(shí)會(huì)發(fā)現(xiàn)另一個(gè)窗口在v$session.status是INACTIVE,并不代表另一個(gè)窗口沒有執(zhí)行過sql語句,而當(dāng)前窗口是active狀態(tài),對(duì)應(yīng)的sql_id對(duì)應(yīng)的語句就是select * from v$session而不是之前執(zhí)行過的sql語句,ACTIVE表示當(dāng)前正在執(zhí)行sql。)

          /* Formatted on 2019/11/6 10:05:33 (QP5 v5.326) */
          SELECT ss.SID,
                 ss.SERIAL#,
                 ss.LOGON_TIME,
                 pr.SPID,
                 sa.SQL_FULLTEXT,
                 ss.machine,
                 ss.TERMINAL,
                 ss.PROGRAM,
                 ss.USERNAME,
                 ss.CLIENT_IDENTIFIER,
                 ss.action,
                 ss.PROCESS     "客戶端機(jī)器進(jìn)程號(hào)",
                 ss.STATUS,
                 ss.OSUSER,
                 ss.status,
                 ss.last_call_et,
                 sa.sql_text
            FROM v$process pr, v$session ss, v$sql sa
           WHERE     pr.ADDR=ss.PADDR
                 AND DECODE (ss.sql_hash_value, 0, prev_hash_value, sql_hash_value)=   sa.hash_value
                 AND pr.spid=&spid

          查看歷史session_id的SQL來自哪個(gè)IP

          查看trace文件名就可以知道spid,trace文件里面有sid和具體sql,如果trace存在incident,那trace就看不到具體sql,但是可以在incident文件中看到具體的sql,如DWora17751.trc中17751就是spid,里面有這樣的內(nèi)容Incident 115 created, dump file: /XX/incident/incdir115/DWora17751i115.trc,那么在DWora17751_i115.trc就可以看到具體的sql語句)

          DBora29349.trc中出現(xiàn)

          *** SESSION ID:(5057.12807) 2016-10-26 14:45:52.726 

          通過表V$ACTIVESESSIONHISTORY來查

          select a.sql_id,a.machine,a.* from V$ACTIVE_SESSION_HISTORY a where a.session_id=5057 and a.SESSION_SERIAL#=12807 

          查詢上面的machine的IP

          select s.sid,s.serial#,s.LOGON_TIME,s.machine,p.spid,p.terminal from v$session s,v$process p where  s.paddr=p.addr and s.machine='localhost' 

          通過上面的spid在oracle服務(wù)器上執(zhí)行netstat -anp |grep spid即可

          [oracle@dwdb trace]$ netstat -anp |grep 17630 tcp      210      0 192.168.64.228:11095        192.168.21.16:1521          ESTABLISHED 17630/oracleDB tcp        0      0 ::ffff:192.168.64.228:1521  ::ffff:192.168.64.220:59848 ESTABLISHED 17630/oracleDB

          出現(xiàn)兩個(gè),說明來自220,連接了228數(shù)據(jù)庫(kù)服務(wù)器,但是又通過228服務(wù)器的dblink去連接了16服務(wù)器

          查詢死鎖堵塞的會(huì)話sid

          最簡(jiǎn)單的一個(gè)SQL

          select * from V$SESSION_BLOCKERS select * from dba_waiters;

          最常用的一個(gè)SQL

          select sid,status,LOGON_TIME,sql_id,blocking_session "死鎖直接源",FINAL_BLOCKING_SESSION "死鎖最終源",event,seconds_in_wait "會(huì)話鎖住時(shí)間_S",LAST_CALL_ET "會(huì)話持續(xù)時(shí)間_S" from v$session where state='WAITING' and BLOCKING_SESSION_STATUS='VALID' and FINAL_BLOCKING_SESSION_STATUS='VALID';

          可以把兩者SID放入v$session,發(fā)現(xiàn)LOGONTIME字段FINALBLOCKING_SESSION比SID要早

          BLOCKINGSESSION:Session identifier of the blocking session. This column is valid only if BLOCKINGSESSIONSTATUS has the value VALID. FINALBLOCKINGSESSION:Session identifier of the blocking session. This column is valid only if FINALBLOCKINGSESSIONSTATUS has the value VALID.

          如果遇到RAC環(huán)境,一定要用gv$來查,并且執(zhí)行alter system kill session 'sid,serial#'要到RAC對(duì)應(yīng)的實(shí)例上去執(zhí)行

          把上面被堵塞會(huì)話的sid代入如下語句,可以發(fā)現(xiàn)鎖住的對(duì)象和對(duì)象的哪一行(如果sid是堵塞源的會(huì)話,則 rowwaitobj#=-1,表示鎖持有者,就是死鎖源了 )

          select s.sid,s.username,d.owner,d.object_name,s.row_wait_obj#,s.row_wait_row#,s.row_wait_file#,s.row_wait_block# from v$session s,dba_objects d where s.row_wait_obj#=d.object_id and s.sid  in(XX,XX);

          查詢鎖住的DDL對(duì)象

          sql

          select d.session_id,s.SERIAL#,d.name from dba_ddl_locks d,v$session s where d.owner='MKLMIGEM' and d.SESSION_ID=s.sid;

          查詢超過兩個(gè)小時(shí)的不活動(dòng)會(huì)話

          select s.sid,s.serial#,p.spid,s.LOGON_TIME,s.LAST_CALL_ET,s.status,s.PROGRAM,s.CLIENT_IDENTIFIER,s.machine,s.terminal,s.action,s.PROCESS "客戶端機(jī)器進(jìn)程號(hào)",s.osuser from v$session s,v$process p  where  s.paddr=p.addr and s.sid in (select sid from v$session where machine<>&DB服務(wù)器名稱 and status='INACTIVE' and sql_id is null and LAST_CALL_ET>7200);

          查詢堵塞別的會(huì)話超過30分鐘且自身是不活動(dòng)的會(huì)話

          select count(ss.SID),ss.machine,ss.status,ss.TERMINAL,ss.PROGRAM,ss.USERNAME,ss.CLIENT_IDENTIFIER  from v$session ss group by ss.machine,ss.status,ss.TERMINAL,ss.PROGRAM,ss.USERNAME,ss.CLIENT_IDENTIFIER having count(ss.SID)>10;

          查詢當(dāng)前正在執(zhí)行的sql

          SELECT s.sid,s.serial#,s.username,spid,v$sql.sql_id,machine,s.terminal,s.program,sql_text  FROM v$process,v$session s,v$sql   WHERE addr=paddr and s.sql_id=v$sql.sql_id AND sql_hash_value=hash_value and s.STATUS='ACTIVE';

          查詢正在執(zhí)行的SCHEDULER_JOB sql

          select owner,job_name,sid,b.SERIAL#,b.username,spid from ALL_SCHEDULER_RUNNING_JOBS,v$session b,v$process  where session_id=sid and paddr=addr;

          查詢正在執(zhí)行的dbms_job

          select job,b.sid,b.SERIAL#,b.username,spid from DBA_JOBS_RUNNING a ,v$session b,v$process  where a.sid=b.sid and paddr=addr;

          查詢一個(gè)會(huì)話session、process平均消耗多少PGA內(nèi)存,查看下面avgusedM值

          /* Formatted on 2019/11/6 10:06:48 (QP5 v5.326) */
          SELECT ROUND (SUM (pga_used_mem) / 1024 / 1024, 0)
                     total_used_M,
                 ROUND (SUM (pga_used_mem) / COUNT (1) / 1024 / 1024, 0)
                     avg_used_M,
                 ROUND (SUM (pga_alloc_mem) / 1024 / 1024, 0)
                     total_alloc_M,
                 ROUND (SUM (pga_alloc_mem) / COUNT (1) / 1024 / 1024, 0)
                     avg_alloc_M
            FROM v$process;

          TOP 10 執(zhí)行次數(shù)排序

          /* Formatted on 2019/11/6 10:07:07 (QP5 v5.326) */
          SELECT *
            FROM (  SELECT executions,
                           username,
                           PARSING_USER_ID,
                           sql_id,
                           sql_text
                      FROM v$sql, dba_users
                     WHERE user_id=PARSING_USER_ID
                  ORDER BY executions DESC)
           WHERE ROWNUM <=5;

          TOP 10 物理讀排序(消耗IO排序,即最差性能SQL、低效SQL排序)

          /* Formatted on 2019/11/6 10:06:06 (QP5 v5.326) */
          SELECT *
            FROM (  SELECT DISK_READS,
                           username,
                           PARSING_USER_ID,
                           sql_id,
                           ELAPSED_TIME / 1000000,
                           sql_text
                      FROM v$sql, dba_users
                     WHERE user_id=PARSING_USER_ID
                  ORDER BY DISK_READS DESC)
           WHERE ROWNUM <=5;

          注意:不要使用DISK_READS/ EXECUTIONS來排序,因?yàn)槿魏我粭l語句不管執(zhí)行幾次都會(huì)耗邏輯讀和cpu,可能不會(huì)耗物理讀(遇到LRU還會(huì)耗物理讀,LRU規(guī)則是執(zhí)行最不頻繁的且最后一次執(zhí)行時(shí)間距離現(xiàn)在最久遠(yuǎn)的就會(huì)被交互出buffer cache),是因?yàn)閎uffer cache存放的是數(shù)據(jù)塊,去數(shù)據(jù)塊里找行一定會(huì)消耗cpu和邏輯讀的。Shared pool執(zhí)行存放sql的解析結(jié)果,sql執(zhí)行的時(shí)候只是去share pool中找hash value,如果有匹配的就是軟解析。所以物理讀邏輯讀是在buffer cache中,軟解析硬解析是在shared pool。

          TOP 10 邏輯讀排序(消耗內(nèi)存排序)

          select * from (select BUFFER_GETS,username,PARSING_USER_ID,sql_id,ELAPSED_TIME/1000000,sql_text from v$sql,dba_users where user_id=PARSING_USER_ID order by BUFFER_GETS desc) where rownum <=5;

          注意:不要使用BUFFER_GETS/ EXECUTIONS來排序,因?yàn)槿魏我粭l語句不管執(zhí)行幾次都會(huì)耗邏輯讀和cpu,可能不會(huì)耗物理讀(遇到LRU還會(huì)耗物理讀,LRU規(guī)則是執(zhí)行最不頻繁的且最后一次執(zhí)行時(shí)間距離現(xiàn)在最久遠(yuǎn)的就會(huì)被交互出buffer cache),是因?yàn)閎uffer cache存放的是數(shù)據(jù)塊,去數(shù)據(jù)塊里找行一定會(huì)消耗cpu和邏輯讀的。Shared pool執(zhí)行存放sql的解析結(jié)果,sql執(zhí)行的時(shí)候只是去share pool中找hash value,如果有匹配的就是軟解析。所以物理讀邏輯讀是在buffer cache中,軟解析硬解析是在shared pool)

          TOP 10 CPU排序(單位秒=cpu_time/1000000)

          select * from (select CPU_TIME/1000000,username,PARSING_USER_ID,sql_id,ELAPSED_TIME/1000000,sql_text from v$sql,dba_users where user_id=PARSING_USER_ID order by CPU_TIME/1000000 desc) where rownum <=5;

          注意:不要使用CPU_TIME/ EXECUTIONS來排序,因?yàn)槿魏我粭l語句不管執(zhí)行幾次都會(huì)耗邏輯讀和cpu,可能不會(huì)耗物理讀(遇到LRU還會(huì)耗物理讀,LRU規(guī)則是執(zhí)行最不頻繁的且最后一次執(zhí)行時(shí)間距離現(xiàn)在最久遠(yuǎn)的就會(huì)被交互出buffer cache),是因?yàn)閎uffer cache存放的是數(shù)據(jù)塊,去數(shù)據(jù)塊里找行一定會(huì)消耗cpu和邏輯讀的。Shared pool執(zhí)行存放sql的解析結(jié)果,sql執(zhí)行的時(shí)候只是去share pool中找hash value,如果有匹配的就是軟解析。所以物理讀邏輯讀是在buffer cache中,軟解析硬解析是在shared pool。

          查詢等待事件

          select event,sum(decode(wait_time,0,0,1)) "之前等待次數(shù)", sum(decode(wait_time,0,1,0))  "正在等待次數(shù)",count(*) from v$session_wait  group by event order by 4 desc;

          查詢當(dāng)前等待事件對(duì)應(yīng)的對(duì)象

          select distinct wait_class#,wait_class from v$session_wait_class order by 1;

          以上sql發(fā)現(xiàn)wait_class#=6的是空閑等待

          select * from(select sid,event,p1text,p1,p2text,p2,p3text,p3,WAIT_TIME,SECONDS_IN_WAIT,wait_class# from v$session_wait where wait_class# <> 6 order by wait_time desc)where rownum <=10;

          能查出等待的對(duì)象是否來自數(shù)據(jù)文件(如果以上查到p1text是file#或file number)

          select * from(select owner,segment_name,segment_type,block_id,bytes from dba_extents where file_id=p1 and block_id<p2 order="" by="" block_id="" desc)where rownum<2

          把上面第二個(gè)sql結(jié)果的p1、p2值代入上述sql的fileid、blockid

          通過AWR的top sql或v$sql.sql_text查看是否有該對(duì)象的語句,檢查該語句的執(zhí)行計(jì)劃就可以查出問題所在。

          查詢當(dāng)前正在消耗臨時(shí)空間的sql語句

          方法一:

          /* Formatted on 2019/11/6 10:08:27 (QP5 v5.326) */
          SELECT DISTINCT
                 se.username,
                 se.sid,
                 su.blocks * TO_NUMBER (RTRIM (p.VALUE)) / 1024 / 1024     AS space_G,
                 su.tablespace,
                 sql_text
            FROM V$TEMPSEG_USAGE  su,
                 v$parameter      p,
                 v$session        se,
                 v$sql            s
           WHERE     p.name='db_block_size'
                 AND su.session_addr=se.saddr
                 AND su.sqlhash=s.hash_value
                 AND su.sqladdr=s.address
                 AND se.STATUS='ACTIVE'

          方法二:

          /* Formatted on 2019/11/6 10:09:13 (QP5 v5.326) */
          SELECT v$sql.sql_id,
                 v$sql.sql_fulltext,
                 swa.TEMPSEG_SIZE / 1024 / 1024     TEMPSEG_M,
                 swa.*
            FROM v$sql_workarea_active swa, v$sql
           WHERE swa.sql_id=v$sql.sql_id AND swa.NUMBER_PASSES > 0

          查詢因PGA不足而使用臨時(shí)表空間的最頻繁的10條SQL語句

          /* Formatted on 2019/11/6 10:07:40 (QP5 v5.326) */
          SELECT *
            FROM (  SELECT OPERATION_TYPE,
                           ESTIMATED_OPTIMAL_SIZE,
                           ESTIMATED_ONEPASS_SIZE,
                           SUM (OPTIMAL_EXECUTIONS)         optimal_cnt,
                           SUM (ONEPASS_EXECUTIONS)         AS onepass_cnt,
                           SUM (MULTIPASSES_EXECUTIONS)     AS mpass_cnt,
                           s.sql_text
                      FROM V$SQL_WORKAREA swa, v$sql s
                     WHERE swa.sql_id=s.sql_id
                  GROUP BY OPERATION_TYPE,
                           ESTIMATED_OPTIMAL_SIZE,
                           ESTIMATED_ONEPASS_SIZE,
                           sql_text
                    HAVING SUM (ONEPASS_EXECUTIONS + MULTIPASSES_EXECUTIONS) > 0
                  ORDER BY SUM (ONEPASS_EXECUTIONS) DESC)
           WHERE ROWNUM < 10

          查詢正在消耗PGA的SQL

          select s.sql_text, sw.EXPECTED_SIZE, sw.ACTUAL_MEM_USED,sw.NUMBER_PASSES, sw.TEMPSEG_SIZE from v$sql_workarea_active sw, v$sql s where sw.sql_id=s.sql_id;

          查詢需要使用綁定變量的sql,10G以后推薦第二種

          注意:任何一條執(zhí)行過的語句不管執(zhí)行了幾次在V$SQL中都只有一條記錄,V$SQL中會(huì)記錄執(zhí)行了幾次。兩條一模一樣的語句但是在不同的schema下執(zhí)行的兩種結(jié)果,如select * from t1.test在sye、system下執(zhí)行則V$SQL只有一條記錄(誰先執(zhí)行則PARSINGSCHEMANAME顯示誰)。如在sys和system都執(zhí)行select * from test則V$SQL中有兩條記錄,兩條記錄的CHILDNUMBER和PARSINGSCHEMA_NAME不一樣。

          同一個(gè)用戶下執(zhí)行一樣的語句如果大小寫不一樣或加了hint的話則會(huì)出現(xiàn)多個(gè)V$SQL記錄,說明V$SQL對(duì)應(yīng)的sql語句必須一模一樣,如果alter system flush sharedpool(主站慎用)后再執(zhí)行一樣的語句,發(fā)現(xiàn)語句在V$SQL中的SQLID和HASHVALUE與之前的一樣,說明SQLID和HASHVALUE應(yīng)該是oracle自己的一套算法來的,只是根據(jù)sql語句內(nèi)容來進(jìn)行轉(zhuǎn)換,sql語句不變則SQLID和HASH_VALUE也不變。

          第一種

          select * from ( select count(*),sql_id, substr(sql_text,1,40) from v$sql group by sql_id, substr(sql_text,1,40) having count(*) > 10 order by count(*) desc) where rownum<10;

          第二種

          count(1)>10表示類語句運(yùn)行了10次以上 select sql_id, FORCE_MATCHING_SIGNATURE, sql_text from v$SQL where FORCE_MATCHING_SIGNATURE in (select /*+ unnest */ FORCE_MATCHING_SIGNATURE from v$sql where FORCE_MATCHING_SIGNATURE > 0 and FORCE_MATCHING_SIGNATURE !=EXACT_MATCHING_SIGNATURE group by FORCE_MATCHING_SIGNATURE having count(1) > 10)

          查看數(shù)據(jù)文件可用百分比

          dbafreespace并不會(huì)包含所有fileid,如果該數(shù)據(jù)文件滿了,則 dbafreespace.fileid沒有該數(shù)據(jù)文件,所以以下sql中 a.fileid=b.fileid的條件過濾后是不會(huì)有所有file_id的

          /* Formatted on 2019/11/6 10:09:31 (QP5 v5.326) */
            SELECT b.file_id,
                   b.tablespace_name,
                   b.file_name,
                   b.AUTOEXTENSIBLE,
                   ROUND (b.MAXBYTES / 1024 / 1024 / 1024, 2) || 'G'
                       "文件最大可用總?cè)萘?#34;,
                   ROUND (b.bytes / 1024 / 1024 / 1024, 2) || 'G'
                       "文件總?cè)萘?#34;,
                      ROUND ((b.bytes - SUM (NVL (a.bytes, 0))) / 1024 / 1024 / 1024, 2)
                   || 'G'
                       "文件已用容量",
                   ROUND (SUM (NVL (a.bytes, 0)) / 1024 / 1024 / 1024, 2) || 'G'
                       "文件可用容量",
                   ROUND (SUM (NVL (a.bytes, 0)) / (b.bytes), 2) * 100 || '%'
                       "文件可用百分比"
              FROM dba_free_space a, dba_data_files b
             WHERE a.file_id=b.file_id
          GROUP BY b.tablespace_name,
                   b.file_name,
                   b.file_id,
                   b.bytes,
                   b.AUTOEXTENSIBLE,
                   b.MAXBYTES
          ORDER BY b.tablespace_name;

          --如下為標(biāo)準(zhǔn)版

          /* Formatted on 2019/11/6 10:10:23 (QP5 v5.326) */
            SELECT b.file_id,
                   b.tablespace_name,
                   b.file_name,
                   b.AUTOEXTENSIBLE,
                   ROUND (b.MAXBYTES / 1024 / 1024 / 1024, 2) || 'G'
                       "文件最大可用總?cè)萘?#34;,
                   ROUND (b.bytes / 1024 / 1024 / 1024, 2) || 'G'
                       "文件當(dāng)前總?cè)萘?#34;,
                      ROUND ((b.bytes - SUM (NVL (a.bytes, 0))) / 1024 / 1024 / 1024, 2)
                   || 'G'
                       "文件當(dāng)前已用容量",
                      ROUND (
                            (  DECODE (AUTOEXTENSIBLE, 'NO', b.BYTES, b.MAXBYTES)
                             + SUM (NVL (a.bytes, 0))
                             - b.bytes)
                          / 1024
                          / 1024
                          / 1024,
                          2)
                   || 'G'
                       "文件可用容量",
                        ROUND (
                              (  DECODE (AUTOEXTENSIBLE, 'NO', b.BYTES, b.MAXBYTES)
                               + SUM (NVL (a.bytes, 0))
                               - b.bytes)
                            / (DECODE (AUTOEXTENSIBLE, 'NO', b.BYTES, b.MAXBYTES)),
                            2)
                      * 100
                   || '%'
                       "文件可用百分比"
              FROM dba_free_space a, dba_data_files b
             WHERE a.file_id=b.file_id
          GROUP BY b.tablespace_name,
                   b.file_name,
                   b.file_id,
                   b.bytes,
                   b.AUTOEXTENSIBLE,
                   b.MAXBYTES
          ORDER BY   DECODE (AUTOEXTENSIBLE, 'NO', b.BYTES, b.MAXBYTES)
                   + SUM (NVL (a.bytes, 0))
                   - b.bytes;

          查看數(shù)據(jù)庫(kù)文件的實(shí)際總量,單位G

          SELECT /*+ USE_MERGE(C,B) */ a.datafile_size + b.tempfile_size - c.free_size 
            FROM (SELECT SUM(bytes / 1024 / 1024 / 1024) datafile_size 
                    FROM dba_data_files) a, 
                 (SELECT SUM(bytes / 1024 / 1024 / 1024) tempfile_size 
                    FROM dba_temp_files) b, 
                 (SELECT SUM(bytes / 1024 / 1024 / 1024) free_size 
                    FROM dba_free_space) c

          查看表空間可用百分比( dbafreespace不會(huì)包含所有tablespace,如果一個(gè)表空間的數(shù)據(jù)文件都滿了,則這個(gè)表空間不會(huì)出現(xiàn)在dbafreespace中 )

          select b.tablespace_name,
                 a.maxsize max_M,
                 a.total total_M,
                 b.free free_M,
                 round((b.free / a.total) * 100) "% Free"
            from (select tablespace_name,
                         sum(bytes / (1024 * 1024)) total,
                         sum(MAXBYTES / (1024 * 1024)) maxsize
                    from dba_data_files
                   group by tablespace_name) a,
                 (select tablespace_name, round(sum(bytes / (1024 * 1024))) free
                    from dba_free_space
                   group by tablespace_name) b
           WHERE a.tablespace_name=b.tablespace_name
           order by "% Free";

          --如下為標(biāo)準(zhǔn)版

          select b.tablespace_name,
                 a.maxsize max_M,
                 a.total total_M,
                 b.free free_M,
                 round(((a.maxsize + b.free - a.total) / a.maxsize) * 100) "% Free"
            from (select tablespace_name,
                         sum(bytes / (1024 * 1024)) total,
                         sum((decode(AUTOEXTENSIBLE, 'NO', BYTES, MAXBYTES)) /
                             (1024 * 1024)) maxsize
                    from dba_data_files
                   group by tablespace_name) a,
                 (select tablespace_name, round(sum(bytes / (1024 * 1024))) free
                    from dba_free_space
                   group by tablespace_name) b
           WHERE a.tablespace_name=b.tablespace_name
           order by "% Free";

          查看臨時(shí)表空間使用率

          方法一

          /* Formatted on 2019/11/6 10:13:28 (QP5 v5.326) */
          SELECT temp_used.tablespace_name,
                 ROUND (total),
                 used,
                 ROUND (total - used)                               AS "Free",
                 ROUND (NVL (total - used, 0) * 100 / total, 1)     "Free percent"
            FROM (  SELECT tablespace_name, SUM (bytes_used) / 1024 / 1024 used
                      FROM GV$TEMP_SPACE_HEADER
                  GROUP BY tablespace_name) temp_used,
                 (  SELECT tablespace_name,
                             SUM (DECODE (autoextensible, 'YES', MAXBYTES, bytes))
                           / 1024
                           / 1024
                               total
                      FROM dba_temp_files
                  GROUP BY tablespace_name) temp_total
           WHERE temp_used.tablespace_name=temp_total.tablespace_name;

          方法二

          /* Formatted on 2019/11/6 10:13:40 (QP5 v5.326) */
          SELECT a.tablespace_name,
                 ROUND (a.BYTES / 1024 / 1024)
                     total_M,
                 ROUND (a.bytes / 1024 / 1024 - NVL (b.bytes / 1024 / 1024, 0))
                     free_M,
                 ROUND (b.bytes / 1024 / 1024)
                     used,
                 ROUND (b.using / 1024 / 1024)
                     using
            FROM (  SELECT tablespace_name,
                           SUM (DECODE (autoextensible, 'YES', MAXBYTES, bytes))
                               bytes
                      FROM dba_temp_files
                  GROUP BY tablespace_name) a,
                 (  SELECT tablespace_name,
                           SUM (bytes_cached)     bytes,
                           SUM (bytes_used)       using
                      FROM v$temp_extent_pool
                  GROUP BY tablespace_name) b
           WHERE a.tablespace_name=b.tablespace_name(+);

          真實(shí)使用率:

          SELECT D.tablespace_name,
                 SPACE "SUM_SPACE(M)",
                 blocks "SUM_BLOCKS",
                 used_space "USED_SPACE(M)",
                 Round(Nvl(used_space, 0) / SPACE * 100, 2) "USED_RATE(%)",
                 SPACE - used_space "FREE_SPACE(M)"
            FROM (SELECT tablespace_name,
                         Round(SUM(bytes) / (1024 * 1024), 2) SPACE,
                         SUM(blocks) BLOCKS
                    FROM dba_temp_files
                   GROUP BY tablespace_name) D,
                 (SELECT tablespace,
                         Round(SUM(blocks * 8192) / (1024 * 1024), 2) USED_SPACE
                    FROM v$sort_usage
                   GROUP BY tablespace) F
           WHERE D.tablespace_name=F.tablespace(+)
             AND D.tablespace_name in ('TEMP', 'TEMP1')

          查詢undo表空間使用情況

          select tablespace_name,status,sum(bytes)/1024/1024 M from dba_undo_extents group by tablespace_name,status;

          查詢使用undo比較多的SQL

           select *from (  select maxqueryid, round(sum(undoblks )*8/1024) consumed_size_MB from v$undostat    group by maxqueryid order by  consumed_size_MB desc ) where rownum<10;

          估計(jì)undo需要多大

          /* Formatted on 2019/11/6 10:14:09 (QP5 v5.326) */
          SELECT (UR * (UPS * DBS/1024/1024))     AS "Mb"
            FROM (SELECT MAX (tuned_undoretention) AS UR FROM v$undostat),
                 (SELECT undoblks / ((end_time - begin_time) * 86400)     AS UPS
                    FROM v$undostat
                   WHERE undoblks=(SELECT MAX (undoblks) FROM v$undostat)),
                 (SELECT block_size     AS DBS
                    FROM dba_tablespaces
                   WHERE tablespace_name=(SELECT UPPER (VALUE)
                                              FROM v$parameter
                                             WHERE name='undo_tablespace'));

          產(chǎn)生undo的當(dāng)前活動(dòng)會(huì)話是哪些

          方法一

          SELECT a.inst_id, a.sid, c.username, c.osuser, c.program, b.name, a.value, d.used_urec, d.used_ublk FROM gv$sesstat a, v$statname b, gv$session c, gv$transaction d WHERE a.statistic#=b.statistic# AND a.inst_id=c.inst_id AND a.sid=c.sid AND c.inst_id=d.inst_id AND c.saddr=d.ses_addr AND b.name='undo change vector size' AND a.value>0 ORDER BY a.value DESC;

          方法二

          select s.sid,s.serial#,s.sql_id,v.usn,r.status, v.rssize/1024/1024 mbfrom dba_rollback_segs r, v$rollstat v,v$transaction t,v$session sWhere r.segment_id=v.usn and v.usn=t.xidusn and t.addr=s.taddrorder by 6 desc;

          查看ASM磁盤組使用率

          select name,round(total_mb/1024) "總?cè)萘?#34;,round(free_mb/1024) "空閑空間",round((free_mb/total_mb)*100) "可用空間比例" from gv$asm_diskgroup;

          統(tǒng)計(jì)每個(gè)用戶使用表空間率

          SELECT c.owner "用戶",
                 a.tablespace_name "表空間名",
                 total / 1024 / 1024 "表空間大小M",
                 free / 1024 / 1024 "表空間剩余大小M",
                 (total - free) / 1024 / 1024 "表空間使用大小M",
                 Round((total - free) / total, 4) * 100 "表空間總計(jì)使用率   %",
                 c.schemas_use / 1024 / 1024 "用戶使用表空間大小M",
                 round((schemas_use) / total, 4) * 100 "用戶使用表空間率  %"
            FROM (SELECT tablespace_name, Sum(bytes) free
                    FROM DBA_FREE_SPACE
                   GROUP BY tablespace_name) a,
                 (SELECT tablespace_name, Sum(bytes) total
                    FROM DBA_DATA_FILES
                   GROUP BY tablespace_name) b,
                 (Select owner, Tablespace_Name, Sum(bytes) schemas_use
                    From Dba_Segments
                   Group By owner, Tablespace_Name) c
           WHERE a.tablespace_name=b.tablespace_name
             and a.tablespace_name=c.Tablespace_Name
           order by "用戶", "表空間名";

          查看閃回區(qū)\快速恢復(fù)區(qū)空間使用率

          select sum(percent_space_used)||'%' "已使用空間比例" from V$RECOVERY_AREA_USAGE 或 select round(100*(a.space_used/space_limit),2)||'%' "已使用空間比例",a.* from v$recovery_file_dest a;

          查看僵死進(jìn)程,分兩種(一種是會(huì)話不在的,另一種是會(huì)話標(biāo)記為killed的但是會(huì)話還在的)

          alter system kill session一執(zhí)行則session即標(biāo)記為KILLED,但是如果會(huì)話產(chǎn)生的數(shù)據(jù)量大則這個(gè)kill可能會(huì)比較久,在這個(gè)過程中session標(biāo)記為KILLED但是這個(gè)會(huì)話還在V$session中,則V$session.paddr還在,所以可以匹配到V$process.addr,所以process進(jìn)程還在;當(dāng)kill過程執(zhí)行完畢,則這個(gè)會(huì)話即不在V$session中

          會(huì)話不在的

          select * from v$process where addr not in (select paddr from v$session) and pid not in (1,17,18);

          會(huì)話還在的,但是會(huì)話標(biāo)記為killed

          select * from v$process where addr in (select paddr from v$session where status='KILLED');

          再根據(jù)上述結(jié)果中的SPID通過如下命令可以查看到process的啟動(dòng)時(shí)間

          ps auxw|head -1;ps auxw|grep SPID

          32. 查看行遷移或行鏈接的表

          select * From dba_tables where nvl(chain_cnt,0)<>0

          chain_cnt :Number of rows in the table that are chained from one data block to another or that have migrated to a new block, requiring a link to preserve the old rowid. This column is updated only after you analyze the table.

          *數(shù)據(jù)緩沖區(qū)命中率(百分比小于90就要加大db_cache_size) *

          SELECT a.VALUE + b.VALUE logical_reads,
                 c.VALUE phys_reads,
                 round(100 * (1 - c.value / (a.value + b.value)), 2) || '%' hit_ratio
            FROM v$sysstat a, v$sysstat b, v$sysstat c
           WHERE a.NAME='db block gets'
             AND b.NAME='consistent gets'
             AND c.NAME='physical reads';

          方法二

          SELECT DB_BLOCK_GETS+CONSISTENT_GETS Logical_reads,PHYSICAL_READS phys_reads, round(100*(1-(PHYSICAL_READS/(DB_BLOCK_GETS+CONSISTENT_GETS))),2)||'%' "Hit Ratio" FROM V$BUFFER_POOL_STATISTICS WHERE NAME='DEFAULT';

          共享池命中率(百分比小于90就要加大sharedpoolsize)

          以下兩者可以根據(jù)個(gè)人理解運(yùn)用

          select sum(pinhits)/sum(pins)*100 from v$librarycache; 
          select sum(pinhits-reloads)/sum(pins)*100 from v$librarycache;

          查詢歸檔日志切換頻率

          select sequence#,
                 to_char(first_time, 'yyyymmdd_hh24:mi:ss') firsttime,
                 round((first_time - lag(first_time) over(order by first_time)) * 24 * 60,
                       1) minutes
            from v$log_history
           where first_time > sysdate - 3
           order by first_time, minutes;

          SELECT TO_CHAR(first_time, 'MM/DD') DAY,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '00', 1, 0)) H00,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '01', 1, 0)) H01,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '02', 1, 0)) H02,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '03', 1, 0)) H03,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '04', 1, 0)) H04,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '05', 1, 0)) H05,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '06', 1, 0)) H06,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '07', 1, 0)) H07,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '08', 1, 0)) H08,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '09', 1, 0)) H09,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '10', 1, 0)) H10,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '11', 1, 0)) H11,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '12', 1, 0)) H12,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '13', 1, 0)) H13,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '14', 1, 0)) H14,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '15', 1, 0)) H15,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '16', 1, 0)) H16,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '17', 1, 0)) H17,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '18', 1, 0)) H18,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '19', 1, 0)) H19,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '20', 1, 0)) H20,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '21', 1, 0)) H21,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '22', 1, 0)) H22,
                 SUM(DECODE(TO_CHAR(first_time, 'HH24'), '23', 1, 0)) H23,
                 COUNT(*) TOTAL
            FROM (SELECT ROWNUM RN, FIRST_TIME
                    FROM V$LOG_HISTORY
                   WHERE first_time > sysdate - 18
                     and FIRST_TIME > ADD_MONTHS(SYSDATE, -1)
                   ORDER BY FIRST_TIME)
           GROUP BY TO_CHAR(first_time, 'MM/DD')
           ORDER BY MIN(RN);

          查詢lgwr進(jìn)程寫日志時(shí)每執(zhí)行一次lgwr需要多少秒,在state是waiting的情況下,某個(gè)等待編號(hào)seq#下,secondsinwait達(dá)多少秒,就是lgwr進(jìn)程寫一次IO需要多少秒

          select event,state,seq#,seconds_in_wait,program from v$session where program like '%LGWR%'  and state='WAITING'

          查詢沒有索引的表

          Select table_name from user_tables where table_name not in (select table_name from user_indexes) Select table_name from user_tables where table_name not in (select table_name from user_ind_columns)

          查詢一個(gè)AWR周期內(nèi)的平均session數(shù)、OS平均負(fù)載、平均db time、平均每秒多少事務(wù)

          select to_char(max(BEGIN_TIME), 'yyyy-mm-dd hh24:mi') ||
                 to_char(max(end_time), '--hh24:mi') time,
                 snap_id,
                 trunc(sum(case metric_name
                             when 'Session Count' then
                              average
                           end),
                       2) sessions,
                 trunc(sum(case metric_name
                             when 'Current OS Load' then
                              average
                           end),
                       2) OS_LOAD,
                 (trunc(sum(case metric_name
                              when 'Database Time Per Sec' then
                               average
                            end),
                        2) / 100) *
                 (ceil((max(end_time) - max(BEGIN_TIME)) * 24 * 60 * 60)) Database_Time_second,
                 trunc(sum(case metric_name
                             when 'User Transaction Per Sec' then
                              average
                           end),
                       2) User_Transaction_Per_Sec
            from dba_hist_sysmetric_summary
           group by snap_id
           order by snap_id;

          --Database Time Per Sec對(duì)應(yīng)值的單位是百分一秒/每秒 --(/100)(ceil((max(end_time)-max(BEGIN_TIME))246060))是代表每個(gè)snap周期內(nèi)的總秒數(shù),oracle 兩個(gè)時(shí)間相減默認(rèn)的是天數(shù),2460*60 為相差的秒數(shù) --這個(gè)SQL查到的DB TIME比較準(zhǔn)確,和awr上面的db time比較一致

          查詢產(chǎn)生熱塊較多的對(duì)象

          x$bh .tch(Touch)表示訪問次數(shù)越高,熱點(diǎn)快競(jìng)爭(zhēng)問題就存在

          SELECT e.owner, e.segment_name, e.segment_type
            FROM dba_extents e,
                 (SELECT *
                    FROM (SELECT addr, ts#, file#, dbarfil, dbablk, tch
                            FROM x$bh
                           ORDER BY tch DESC)
                   WHERE ROWNUM < 11) b
           WHERE e.relative_fno=b.dbarfil
             AND e.block_id <=b.dbablk
             AND e.block_id + e.blocks > b.dbablk;

          手工創(chuàng)建快照的語句

          exec dbms_workload_repository.create_snapshot; 

          AWR設(shè)置每隔30分鐘收集一次報(bào)告,保留14天的報(bào)告

          exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(retention=>14*24*60, interval=>30); select * from dba_hist_wr_control;

          AWR基線查看和創(chuàng)建

          select * from dba_hist_baseline; exec DBMS_WORKLOAD_REPOSITORY.CREATE_BASELINE(start_snap_id=>7550,end_snap_id=>7660,baseline_name=>'am_baseline');

          導(dǎo)出AWR報(bào)告的SQL語句

          select * from dba_hist_snapshot select * from table(dbms_workload_repository.awr_report_html(DBID, INSTANCE_NUMBER, startsnapid,endsnapid)) select * from TABLE(DBMS_WORKLOAD_REPOSITORY.awr_diff_report_html(DBID, INSTANCE_NUMBER, startsnapid,endsnapid, DBID, INSTANCE_NUMBER, startsnapid,endsnapid));

          導(dǎo)出最新ADDM的報(bào)告(需要sys用戶)

          select dbms_advisor.get_task_report(task_name) from dba_advisor_tasks where task_id=( select max(t.task_id) from dba_advisor_tasks t, dba_advisor_log l where  t.task_id=l.task_id and t.advisor_name='ADDM' and l.status='COMPLETED' ); select task_id,task_name,description from dba_advisor_tasks order by 1 desc select dbms_advisor.get_task_report(task_name) from dba_advisor_tasks where task_id=XX 

          查詢某個(gè)SQL的執(zhí)行計(jì)劃

          select * from table(dbms_xplan.display_cursor('sql_id',0,' advanced '));

          上面的0表示v$sql.childnumber為0,如果一個(gè)sqlid在v$sql中有多行說明有多個(gè)childnumber,要看哪兒childnumber的執(zhí)行計(jì)劃,就寫哪個(gè)的值,比如要看child_number為2的執(zhí)行計(jì)劃,就把上面sql的0改為2 。

          官方文檔對(duì)display_cursor這個(gè)函數(shù)的說明里面沒有advanced這個(gè)參數(shù)值,只有BASIC、TYPICAL、ALL這幾個(gè),不過實(shí)踐中發(fā)現(xiàn)advanced這個(gè)參數(shù)值顯示的內(nèi)容比這幾個(gè)參數(shù)值顯示的都多。

          select * from table(xplan.display_cursor('v$sql.sql_id',0,'advanced'));

          創(chuàng)建xplan包,再執(zhí)行

          SQL> CREATE PUBLIC SYNONYM XPLAN FOR SYS.XPLAN; SQL> grant execute on sys.xplan to public;

          查詢Rman的配置信息

          SELECT NAME,VALUE FROM V$RMAN_CONFIGURATION;

          查詢Rman備份集詳細(xì)信息(未過期的,過期并已刪除的查不到)

          SELECT B.RECID BackupSet_ID,
                 A.SET_STAMP,
                 DECODE(B.INCREMENTAL_LEVEL,
                        '',
                        DECODE(BACKUP_TYPE, 'L', 'Archivelog', 'Full'),
                        1,
                        'Incr-1級(jí)',
                        0,
                        'Incr-0級(jí)',
                        B.INCREMENTAL_LEVEL) "Type LV",
                 B.CONTROLFILE_INCLUDED "包含CTL",
                 DECODE(A.STATUS,
                        'A',
                        'AVAILABLE',
                        'D',
                        'DELETED',
                        'X',
                        'EXPIRED',
                        'ERROR') "STATUS",
                 A.DEVICE_TYPE "Device Type",
                 A.START_TIME "Start Time",
                 A.COMPLETION_TIME "Completion Time",
                 A.ELAPSED_SECONDS "Elapsed Seconds",
                 A.BYTES / 1024 / 1024 / 1024 "Size(G)",
                 A.COMPRESSED,
                 A.TAG "Tag",
                 A.HANDLE "Path"
            FROM GV$BACKUP_PIECE A, GV$BACKUP_SET B
           WHERE A.SET_STAMP=B.SET_STAMP
             AND A.DELETED='NO'
           ORDER BY A.COMPLETION_TIME DESC;

          查詢Rman備份進(jìn)度

          SELECT SID, SERIAL#, opname,ROUND(SOFAR/TOTALWORK*100)||'%' "%_COMPLETE", TRUNC(elapsed_seconds/60) || ':' || MOD(elapsed_seconds,60) elapsed, TRUNC(time_remaining/60) || ':' || MOD(time_remaining,60) remaining, CONTEXT,target,SOFAR, TOTALWORK FROM V$SESSION_LONGOPS WHERE OPNAME LIKE 'RMAN%' AND OPNAME NOT LIKE '%aggregate%' AND TOTALWORK !=0 AND SOFAR <> TOTALWORK; 

          查詢執(zhí)行過全表掃描的sql語句的SQLID和sqlfulltext

          select s.sid,s.serial#,s.inst_id,s.sql_id,s.username,s.target,s.ELAPSED_SECONDS,s.START_TIME,s.LAST_UPDATE_TIME,v.sql_fulltext   from gv$session_longops s,gv$sql v where s.OPNAME='Table Scan'    and s.SQL_PLAN_OPERATION='TABLE ACCESS'    and s.SQL_PLAN_OPTIONS='FULL'    and s.sql_id=v.sql_id    order by s.LAST_UPDATE_TIME desc 

          查詢死事務(wù)需要多長(zhǎng)的回滾時(shí)間

          X$KTUXE:[K]ernel [T]ransaction [U]ndo Transa[x]tion [E]ntry (table)

          X$KTUXE表的一個(gè)重要功能是,可以獲得無法通過v$transaction來觀察的死事務(wù)信息,當(dāng)一個(gè)數(shù)據(jù)庫(kù)發(fā)生異常中斷,或者進(jìn)行延遲事務(wù)恢復(fù)時(shí),數(shù)據(jù)庫(kù)啟動(dòng)后,無法通過V$TRANSACTION來觀察事務(wù)信息,但是X$KTUXE可以幫助我們獲得這些信息。該表中的KTUXECFL代表了事務(wù)的Flag標(biāo)記,通過這個(gè)標(biāo)記可以找到那些Dead事務(wù):

          SQL> select distinct KTUXECFL,count(*) from x$ktuxe group by KTUXECFL;     KTUXECFL                  COUNT(*)     ------------------------ ----------     DEAD                              1 NONE                          2393 

          KTUXESIZ用來記錄事務(wù)使用的回滾段塊數(shù),可以通過觀察這個(gè)字段來評(píng)估恢復(fù)進(jìn)度,例如如下事務(wù)回滾經(jīng)過測(cè)算需要大約3小時(shí):

          SQL> select ADDR,KTUXEUSN,KTUXESLT,KTUXESQN,KTUXESIZ from x$ktuxe where  KTUXECFL='DEAD';     ADDR              KTUXEUSN  KTUXESLT  KTUXESQN  KTUXESIZ     ---------------- ---------- ---------- ---------- ---------- FFFFFFFF7D07B91C        10        39    2567412    1086075 
          SQL> select ADDR,KTUXEUSN,KTUXESLT,KTUXESQN,KTUXESIZ from x$ktuxe where  KTUXECFL='DEAD';     ADDR              KTUXEUSN  KTUXESLT  KTUXESQN  KTUXESIZ     ---------------- ---------- ---------- ---------- ----------     FFFFFFFF7D07B91C        10        39    2567412    1086067 
          SQL> declare    l_start number;    l_end    number;    begin     select ktuxesiz into l_start from x$ktuxe where  KTUXEUSN=10 and KTUXESLT=39;     dbms_lock.sleep(60);     select ktuxesiz into l_end from x$ktuxe where  KTUXEUSN=10 and KTUXESLT=39;     dbms_output.put_line('time_H:'|| round(l_end/(l_start -l_end)/60,2));   end;   / 
          time_H:3 

          把XXX用戶下面的某些YYY表賦權(quán)給user,XXX\YYY要大寫

          set serveroutput on --XXX要大寫 declare tablename varchar2(200);         begin     for x IN (SELECT * FROM dba_tables where owner='XXX' and table_name like '%YYY%') loop       tablename:=x.table_name;     dbms_output.put_line('GRANT SELECT ON XXX.'||tablename||' to user');     EXECUTE IMMEDIATE 'GRANT SELECT ON XXX.'||tablename||' TO user';      end loop; end; 

          Oracle查出一個(gè)用戶具有的所有系統(tǒng)權(quán)限和對(duì)象權(quán)限

          系統(tǒng)權(quán)限(和用戶自己查詢select * from session_privs的結(jié)果一致)

          SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE='用戶名' UNION ALL SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE IN (SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE='用戶名');

          對(duì)象權(quán)限(和用戶自己查詢select * FROM TABLE_PRIVILEGES where GRANTEE='當(dāng)前用戶'的結(jié)果一致)

          SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE='用戶名' UNION ALL SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE IN (SELECT GRANTED_ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE='用戶名');

          查詢某個(gè)用戶擁有的角色

          select * from dba_role_privs where GRANTEE='用戶名'; 

          查詢擁有DBA角色權(quán)限的用戶

          select * from dba_role_privs where GRANTED_ROLE='DBA'; 

          查詢某個(gè)角色擁有的系統(tǒng)權(quán)限

          select * from ROLE_SYS_PRIVS where role='角色名' 

          清除某個(gè)SQL的執(zhí)行計(jì)劃

          Exec DBMS_SHARED_POOL.PURGE('v$sqlarea.ADDRESS,v$sqlarea.HASH_VALUE','c') 

          查詢密碼是否有過期限制,默認(rèn)是180天,一般修改為unlimited

          select * from dba_profiles where profile='DEFAULT' and RESOURCE_NAME like 'PASSWORD%'; ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED 

          查詢和修改隱含參數(shù)(必須在sysdba權(quán)限下操作)

          select a.ksppinm name, b.ksppstvl value, a.ksppdesc description   from x$ksppi a, x$ksppcv b  where a.indx=b.indx and a.ksppinm like '%_small_table_threshold%' alter system set "_small_table_threshold"=value scope=both sid='*'; 

          不加sid則說明在默認(rèn)在RAC的所有實(shí)例中修改 需要注意的是一定要加上雙引號(hào), 另外引號(hào)內(nèi)不能有空格, 只能包含參數(shù)的名字

          評(píng)估PGA該設(shè)置多少

          select PGA_TARGET_FOR_ESTIMATE from (select  * from V$PGA_TARGET_ADVICE where ESTD_OVERALLOC_COUNT=0 order by 1) where rownum=1; 

          評(píng)估SGA該設(shè)置多少

          select SGA_SIZE from (select * from V$SGA_TARGET_ADVICE where ESTD_DB_TIME_FACTOR=1 order by 1) where rownum=1; 

          查看shared pool還剩多少

          select * from v$sgastat where name='free memory' and pool='shared pool'; 

          統(tǒng)計(jì)所有表的容量大小(含分區(qū)字段、LOB字段) 一般先執(zhí)行select distinct SEGMENTTYPE from dbasegments where owner<>'SYS' and tablespacename<>'SYSAUX'查看到所有的segmenttype

          如下SQL就足夠了

          SELECT owner, table_name, TRUNC(sum(bytes) / 1024 / 1024) AS "SIZE(MB)"
            FROM (SELECT segment_name table_name, owner, bytes
                    FROM dba_segments
                   WHERE segment_type='TABLE'
                  UNION ALL
                  SELECT s.segment_name table_name, pt.owner, s.bytes
                    FROM dba_segments s, dba_part_tables pt
                   WHERE s.segment_name=pt.table_name
                     AND s.owner=pt.owner
                     AND s.segment_type='TABLE PARTITION'
                  UNION ALL
                  SELECT i.table_name, i.owner, s.bytes
                    FROM dba_indexes i, dba_segments s
                   WHERE s.segment_name=i.index_name
                     AND s.owner=i.owner
                     AND s.segment_type='INDEX'
                  UNION ALL
                  SELECT pi.table_name, pi.owner, s.bytes
                    FROM dba_part_indexes pi, dba_segments s
                   WHERE s.segment_name=pi.index_name
                     AND s.owner=pi.owner
                     AND s.segment_type='INDEX PARTITION'
                  UNION ALL
                  SELECT l.table_name, l.owner, s.bytes
                    FROM dba_lobs l, dba_segments s
                   WHERE s.segment_name=l.segment_name
                     AND s.owner=l.owner
                     AND s.segment_type='LOBSEGMENT'
                  UNION ALL
                  SELECT l.table_name, l.owner, s.bytes
                    FROM dba_lobs l, dba_segments s
                   WHERE s.segment_name=l.index_name
                     AND s.owner=l.owner
                     AND s.segment_type='LOBINDEX'
                  union all
                  SELECT l.table_name, l.owner, s.bytes
                    FROM dba_lobs l, dba_segments s
                   WHERE s.segment_name=l.segment_name
                     AND s.owner=l.owner
                     AND s.segment_type='LOB PARTITION')
           GROUP BY owner, table_name
          HAVING SUM(bytes) / 1024 / 1024 > 10
           ORDER BY SUM(bytes) desc

          查看當(dāng)前會(huì)話的SID

          select * from V$MYSTAT where rownum<2 

          查詢某個(gè)SID的某個(gè)統(tǒng)計(jì)信息,比如consistent gets一致性讀

          select A.SID,A.STATISTIC#,A.VALUE SID_VALUE,B.NAME,B.VALUE ALL_SID_VALUE from V$SESSTAT A ,V$SYSSTAT B where A.STATISTIC#=B.STATISTIC# and A.SID=1187 and B.NAME='consistent gets' 

          V$SYSSTAT統(tǒng)計(jì)整個(gè)DB的統(tǒng)計(jì)信息,V$SYSSTAT已經(jīng)取代了V$STATNAME,并且多了VALUE這一列 V$SESSTAT統(tǒng)計(jì)每個(gè)用戶的統(tǒng)計(jì)信息 查詢某個(gè)SID的某個(gè)等待事件的信息,比如log file sync

          select A.SID,A.EVENT,C.NAME,C.PARAMETER1,C.PARAMETER2,C.PARAMETER3, A.TIME_WAITED SID_TIMEWAITED,B.TIME_WAITED ALL_SID_TIMEWAITED,A.TOTAL_WAITS SID_TOTALWAITS,B.TOTAL_WAITS ALL_SID_TOTALWAITS from V$SESSION_EVENT A ,V$SYSTEM_EVENT B,V$EVENT_NAME C where A.EVENT=B.EVENT and A.EVENT=C.NAME and A.SID=1 and C.NAME='log file sync'

          V$SESSION_EVENT描述每個(gè)用戶的等待事件信息 V$SYSTEM_EVENT描述整個(gè)DB等待事件信息 V$EVENT_NAME描述等待事件信本身的信息(比如 V$ACTIVE_SESSION_HISTORY的P1TEXT、P2TEXT、P2TEXT匹配 V$EVENT_NAME的PARAMETER1、PARAMETER2、PARAMETER3)

          RAC跨節(jié)點(diǎn)殺會(huì)話

          alter system kill session 'SID,serial#,@1'  --殺掉1節(jié)點(diǎn)的進(jìn)程 alter system kill session 'SID,serial#,@2'  --殺掉2節(jié)點(diǎn)的進(jìn)程 

          Truncate 分區(qū)的SQL

          ALTER TABLE table_name TRUNCATE PARTITION p1 DROP STORAGE UPDATE GLOBAL INDEXES; 

          Drop分區(qū)的SQL

          ALTER TABLE table_name DROP PARTITION p1 UPDATE GLOBAL INDEXES; 

          DATAGUARD主備延遲多少時(shí)間的查詢方法 備 庫(kù)

          select value from v$dataguard_stats where name='apply lag'

          或 備庫(kù)

          sqlplus>select ceil((sysdate-next_time)*24*60) "M" from v$archived_log where applied='YES' AND SEQUENCE#=(SELECT MAX(SEQUENCE#)  FROM V$ARCHIVED_LOG WHERE applied='YES'); 

          查看某個(gè)包或存儲(chǔ)過程是否正在被調(diào)用,如果如下有結(jié)果,則此時(shí)不能編譯,否則會(huì)鎖住

          select * from V$DB_OBJECT_CACHE where pin>0 and name=upper('XX')

          查詢數(shù)據(jù)庫(kù)打補(bǔ)丁的記錄

          select * from dba_registry_history;

          查詢某表的索引字段的distinct行數(shù)和CLUSTERING_FACTOR信息

          select a.table_name,
                 a.index_name,
                 b.COLUMN_NAME,
                 a.blevel,
                 a.distinct_keys,
                 A.CLUSTERING_FACTOR,
                 A.NUM_ROWS,
                 trunc((a.distinct_keys / A.NUM_ROWS), 2) * 100 || '%' "distinct%",
                 trunc((a.CLUSTERING_FACTOR / A.NUM_ROWS), 2) * 100 || '%' "CLUSTERING_FACTOR%"
            from DBA_IND_STATISTICS a, DBA_IND_COLUMNS b
           where a.table_name='XX'
             and a.INDEX_NAME=b.index_name
           order by 5 desc

          查詢某表的所有字段的distinct行數(shù)

          select a.table_name,
                 b.num_rows,
                 a.column_name,
                 a.data_type,
                 a.data_length,
                 a.num_distinct,
                 trunc((a.num_distinct / b.num_rows), 2) * 100 || '%'
            from dba_TAB_COLS a, dba_tables b
           where a.table_name='XX'
             and a.table_name=b.table_name
           order by 6 desc

          查詢5G以上空閑空間可以進(jìn)行收縮的數(shù)據(jù)文件

          者介紹

          梁敬彬,福富研究院副理事長(zhǎng)、公司唯一四星級(jí)內(nèi)訓(xùn)師,國(guó)內(nèi)一線知名數(shù)據(jù)庫(kù)專家,在數(shù)據(jù)庫(kù)優(yōu)化和培訓(xùn)領(lǐng)域有著豐富的經(jīng)驗(yàn)。多次應(yīng)邀擔(dān)任國(guó)內(nèi)外數(shù)據(jù)庫(kù)大會(huì)的演講嘉賓,在業(yè)界有著廣泛的影響力。著有多本暢銷書籍,代表作有《收獲,不止Oracle》。文末將有梁老師的新書《收獲,不止SQL優(yōu)化》大彩蛋哦~

          SQL優(yōu)化是一個(gè)復(fù)雜的工程,首先要講究從整體到局部。今天我們首先學(xué)習(xí)關(guān)于數(shù)據(jù)庫(kù)整體優(yōu)化都有哪些性能工具,接著分析這些工具的特點(diǎn),并結(jié)合案例進(jìn)行探索,最后再進(jìn)行總結(jié)和思考。

          總體學(xué)習(xí)思路如下圖所示:

          都有哪些性能工具

          這里首先要分成兩部分:一種是不同調(diào)優(yōu)場(chǎng)景的分析,可分為單純場(chǎng)景的優(yōu)化和復(fù)雜場(chǎng)景的優(yōu)化;而另一種是基于這些場(chǎng)景的工具應(yīng)用,就是針對(duì)單純場(chǎng)景的優(yōu)化手段和復(fù)雜場(chǎng)景的優(yōu)化手段。

          1、不同調(diào)優(yōu)場(chǎng)景分析

          我們繼續(xù)探討,單純是有多單純呢?哦,其實(shí)可以理解為無菌真空實(shí)驗(yàn)室里的實(shí)驗(yàn)。比如一條SQL很慢,原因是未走高效的索引查詢而走全表掃描,加個(gè)索引就快了,執(zhí)行速度從10s變成了0.1s;或者一條SQL執(zhí)行速度被優(yōu)化到1s左右,邏輯讀控制在50個(gè)左右,應(yīng)該就已經(jīng)OK。這就是單純的環(huán)境,我們差不多無須再考慮優(yōu)化了。

          那啥是復(fù)雜呢?那就是,剛才那個(gè)語句加了索引后,本應(yīng)該從10s變成0.1s,結(jié)果還是10s,甚至變成30s了,這是咋回事呢?原來,現(xiàn)在系統(tǒng)是整體出問題了,數(shù)據(jù)庫(kù)主機(jī)資源耗盡,啥語句都跑不快的。

          還有那個(gè)邏輯讀在50左右的SQL,如果一天執(zhí)行幾百幾千萬次,這要是能將邏輯讀降低一點(diǎn),得省多少的邏輯讀啊。原來復(fù)雜環(huán)境真的很復(fù)雜,要考慮SQL本身沒問題而是被環(huán)境影響,還要考慮SQL的執(zhí)行頻率,判斷其調(diào)優(yōu)價(jià)值與調(diào)優(yōu)空間,這些在單純的環(huán)境里,是不用考慮的。

          2、不同場(chǎng)景對(duì)應(yīng)工具

          接下來,我們說說這兩種場(chǎng)景對(duì)應(yīng)的工具的使用。關(guān)于局部分析調(diào)優(yōu)工具,這個(gè)其實(shí)就是在說SQL的執(zhí)行計(jì)劃了,這是SQL優(yōu)化最重要的手段之一,通過分析執(zhí)行計(jì)劃,我們可以知道SQL語句的訪問路徑,知道它慢在哪里,從而進(jìn)行SQL優(yōu)化。由于在隨后的章節(jié)中我們會(huì)詳細(xì)介紹執(zhí)行計(jì)劃相關(guān)知識(shí),這里就不再細(xì)述了。

          關(guān)于整體的調(diào)優(yōu)工具,這里我們先撇開主機(jī)、網(wǎng)絡(luò)、存儲(chǔ)等層面的因素,暫時(shí)從數(shù)據(jù)庫(kù)的整體層面入手。主要工具有AWR、ASH、ADDM、AWRDD這四個(gè)工具。其中AWR是關(guān)注數(shù)據(jù)庫(kù)的整體性能的報(bào)告;ASH是數(shù)據(jù)庫(kù)中的等待事件與哪些SQL具體對(duì)應(yīng)的報(bào)告;ADDM是Oracle給出的一些建議;而AWRDD是Oracle針對(duì)不同時(shí)段的性能的一個(gè)比對(duì)報(bào)告,比如今天早上9點(diǎn)系統(tǒng)很慢,而昨天這個(gè)時(shí)候很正常,很多人就想知道今天早上9點(diǎn)和昨天早上9點(diǎn)有什么不同,于是就有了這個(gè)報(bào)告。

          整體分析調(diào)優(yōu)是必需的,那么我們對(duì)此的學(xué)習(xí)也有規(guī)律可循。首先是獲取系統(tǒng)整體信息的手段,一般通過報(bào)告和日志獲取。好比破案一樣,這就是收集證據(jù)的階段。接下來要找到蛛絲馬跡,那就是如何發(fā)現(xiàn)問題。在本書中就是需要關(guān)注提取到的這些報(bào)告的哪些要點(diǎn)、哪些關(guān)鍵字,具體流程圖如下:

          整體性能工具的要點(diǎn)

          現(xiàn)代人對(duì)健康都比較重視,每年都會(huì)進(jìn)行健康體檢。其實(shí)數(shù)據(jù)庫(kù)性能工具的應(yīng)用(報(bào)告獲取和關(guān)注要點(diǎn))和體檢是非常類似的。

          1. 報(bào)告的獲取

          Oracle性能報(bào)告分成AWR、ASH、ADDM、AWRDD和AWRSQRPT這5個(gè)類型。

          什么?這么多,好復(fù)雜啊,記也記不住,我不想聽不想聽!

          別急,你只要去醫(yī)院體檢過,你就能聽懂。

          Really?

          我們?nèi)メt(yī)院體檢,最終會(huì)得到一份體檢報(bào)告,往往能看到很多總體性指標(biāo),這些指標(biāo)會(huì)判斷你是否健康。沒毛病最好,萬一有毛病,報(bào)告里要進(jìn)一步判斷是什么毛病,是高血壓,還是骨質(zhì)增生,還是胃有毛病……這就是現(xiàn)實(shí)中的體檢報(bào)告。

          而Oracle提供的一種性能收集和分析工具,它能提供一個(gè)時(shí)間段內(nèi)整個(gè)系統(tǒng)資源使用情況的報(bào)告,這個(gè)報(bào)告里有很多總體性指標(biāo)來判斷系統(tǒng)是否健康。沒毛病最好,萬一有毛病,問題出在什么模塊,是日志切換過于頻繁,還是硬解析過大,還是某些SQL相關(guān)等待事件在耗資源……這就是AWR報(bào)告。這樣看來,體檢報(bào)告和AWR報(bào)告非常類似。

          假設(shè)體檢報(bào)告說你有胃病,很可能只告訴你胃有問題,卻無法告訴你具體啥毛病,因?yàn)槟闶稚系捏w檢報(bào)告不會(huì)詳細(xì)到擁有你胃部所有相關(guān)指標(biāo)。你要得到這些指標(biāo)需要做進(jìn)一步信息收集,那就是胃鏡。同樣假設(shè)你的數(shù)據(jù)庫(kù)是SQL相關(guān)等待事件問題,AWR報(bào)告很可能只告訴你有這個(gè)問題而無法告訴你是哪些SQL引發(fā)的。你要得到這些指標(biāo),想了解具體某些SQL和相關(guān)等待事件的對(duì)應(yīng)需要做進(jìn)一步的信息收集,那就是ASH報(bào)告。看來對(duì)比胃鏡和ASH報(bào)告,二者也非常類似。

          剛才說的胃病,或許是醫(yī)生告訴你的,因?yàn)樯厦嬗泻芏嘀笜?biāo)你無法讀懂,這時(shí)如果你能拿到一張醫(yī)生的病歷卡記錄,這里沒有指標(biāo),只有白底黑字用文字描述的病情,告訴你要如何治療,那你一定會(huì)看得很明白。同樣假設(shè),如果將含各種晦澀的指標(biāo)的數(shù)據(jù)庫(kù)體檢報(bào)告用一些白底黑字的文字代替,用文字直接說明數(shù)據(jù)庫(kù)遇到了什么問題,告訴你該如何去優(yōu)化,那新手一定會(huì)看得很明白,這就是ADDM報(bào)告。看來病歷卡記錄和ADDM報(bào)告,二者也非常類似。

          假如你在一年前也做過體檢,并將報(bào)告帶到了醫(yī)院,負(fù)責(zé)任的醫(yī)生就一定會(huì)讓你將舊的體檢報(bào)告也提供給他。他會(huì)認(rèn)真地比對(duì)兩張報(bào)告,查看他關(guān)注的健康指標(biāo)是否有異常波動(dòng),這些波動(dòng)對(duì)醫(yī)生很有參考意義,往往預(yù)示著病情的發(fā)展趨勢(shì)。好了,別緊張,這只是比喻。

          假設(shè)你有系統(tǒng)新舊兩個(gè)時(shí)段的兩份AWR報(bào)告,負(fù)責(zé)任的DBA一定會(huì)讓你將舊的AWR報(bào)告也提供給他。他會(huì)認(rèn)真地比對(duì)兩份報(bào)告,查看他關(guān)注的數(shù)據(jù)庫(kù)指標(biāo)是否有異常波動(dòng),這些波動(dòng)對(duì)DBA很有參考意義,往往預(yù)示著數(shù)據(jù)庫(kù)性能瓶頸的發(fā)展趨勢(shì)。Oracle提供了一個(gè)工具能夠?qū)蓚€(gè)時(shí)段的AWR報(bào)告合并,并能方便地顯示出比對(duì)信息,這個(gè)工具就是AWRDD。看來醫(yī)生分析前后兩次體檢報(bào)告的動(dòng)作和AWRDD報(bào)告比起來,兩者也非常類似。

          大家知道做胃鏡是一件很麻煩的事(類似ASH報(bào)告),如果沒毛病就沒必要讓我們?cè)膺@罪。可萬一體檢報(bào)告無情地告訴你胃有毛病,甚至是醫(yī)生分析你前后兩次體檢報(bào)告(類似ADDM)后告訴你胃病在加速中,你被迫無奈只好去做胃鏡了。做完后醫(yī)生發(fā)現(xiàn)你胃部有大量息肉,卻無法判斷這些息肉是否為良性。于是還要做進(jìn)一步的檢查,這就是活檢。不要緊張,平時(shí)注意健康生活就好。同樣ASH報(bào)告判斷出某些SQL有問題,卻無法得到執(zhí)行計(jì)劃等更詳細(xì)的信息,只能依靠AWRSQRPT去獲取這些信息。看來活檢和AWRSQRPT報(bào)告比起來,兩者也非常類似。

          最后恭喜你,活檢報(bào)告顯示未產(chǎn)生癌變,只要好好治療,注意身體,胃就能恢復(fù)健康!看本書的讀者們,你們都是IT人士,生活無規(guī)律加班熬夜者居多,一定要注意身體哦!

          對(duì)了,還有一件最重要的事沒交代。大家似乎搞懂了Oracle五大性能報(bào)告,可是這些好東西在哪里才能得到呢?別著急,后續(xù)章節(jié)馬上就會(huì)告訴你如何獲取這五大性能報(bào)告。

          2. 報(bào)告的關(guān)注點(diǎn)

          如果患者拿著有各種晦澀指標(biāo)的體檢報(bào)告來到門診請(qǐng)教醫(yī)生,他一定會(huì)關(guān)注各種指標(biāo)來判斷患者具體是什么毛病。同樣你也會(huì)對(duì)Oracle的性能報(bào)告中的各種指標(biāo)進(jìn)行關(guān)注來判斷數(shù)據(jù)庫(kù)出了什么毛病。兩者非常類似,關(guān)注不同的指標(biāo),都是為了施救,前者救人,后者救數(shù)據(jù)庫(kù)。

          聽起來是不是很激動(dòng),恨不得馬上就要開始當(dāng)救庫(kù)英雄了!別急,接下來還要告訴你關(guān)注什么,然后在案例中讓你感受一下什么叫救庫(kù)英雄。

          特別提醒:

          這里有一個(gè)特別值得注意的地方,那就是性能報(bào)告的采樣時(shí)間。Oracle默認(rèn)是每小時(shí)產(chǎn)生一個(gè)采樣點(diǎn),你可以收集每個(gè)小時(shí)的性能報(bào)告。我們對(duì)此要敏感,比如你的性能故障是發(fā)生在今天早上7點(diǎn)~8點(diǎn)。然后系統(tǒng)自動(dòng)恢復(fù)了,你獲取一張8點(diǎn)~9點(diǎn)的性能報(bào)告來查問題,就毫無意義了。

          3、五大性能報(bào)告的獲取1AWR的獲取與說明

          獲取AWR報(bào)告的方式有兩種:一種是直接獲取方式,調(diào)后臺(tái)腳本awrrpt.sql來獲取,執(zhí)行方式一般是在sqlplus下執(zhí)行@?/rdbms/admin/awrrpt.sql;

          另一種則是通過調(diào)用命令包,獲取dbms_workload_repository這個(gè)包的awr_report_html程序,用SQL命令的形式輸出內(nèi)容。

          Select output from table(dbms_workload_repository.awr_report_html

          (v_dbid, v_instance_number,v_min_snap_id,v_max_snap_id))

          (1)直接獲取

          試驗(yàn)1(未使用批量提交):

          接下來通過提示就可以生成AWR報(bào)告了,具體步驟略去,詳情請(qǐng)掃本章最后的二維碼。

          試驗(yàn)2(單機(jī)下,正確使用批量提交):

          接下來通過提示就可以生成awr報(bào)告了,具體步驟略去。

          (2)通過調(diào)用命令包獲取

          直接調(diào)用工具包的方式,特別適合用在程序自動(dòng)獲取報(bào)告的場(chǎng)景。

          注:其中977587123是數(shù)據(jù)庫(kù)的主機(jī)標(biāo)識(shí),可以在數(shù)據(jù)庫(kù)的數(shù)據(jù)字典中查到,1是標(biāo)識(shí)實(shí)例,如果是RAC,就有1和2兩個(gè),單機(jī)就只有1。1920和1921是兩個(gè)斷點(diǎn)時(shí)間,比如9點(diǎn)和10點(diǎn)之間。

          2ASH的獲取與說明

          獲取ASH報(bào)告的方式也有兩種:一種是直接獲取方式,調(diào)后臺(tái)腳本ashrpt.sql來獲取,執(zhí)行方式一般是在sqlplus下執(zhí)行@?/rdbms/admin/ashrpt.sql;另一種則是通過調(diào)用命令包,獲取dbms_workload_repository這個(gè)包的ash_report_html程序。用SQL命令的形式輸出內(nèi)容。

          select output from table(dbms_workload_

          repository.ash_report_html( dbid,inst_num,l_btime,l_etime)

          (1)直接獲取

          說明:

          1. 如果你是一路回車,就是獲取最近5分鐘的ASH報(bào)告。

          2. 如果你根據(jù)Oldest ASH sample available 時(shí)間,然后回車,選擇的是目前可收集的最長(zhǎng)ASH運(yùn)行情況。

          3. 你可以選擇Oldest ASH sample available和Latest ASH sample available之間時(shí)間,然后輸入時(shí)長(zhǎng),比如30表示30分鐘,取你要取的任何時(shí)段的ASH報(bào)告。

          4. ASH報(bào)告的獲取不同于AWR的地方在于,快照之間有無重啟動(dòng)作不影響報(bào)告的獲取。

          5. ASH報(bào)告可以直接手工獲取,比如select output from table(dbms_workload_ repository.ash_report_html( dbid,inst_num,l_btime,l_etime)。

          (2)通過調(diào)用命令包獲取

          直接調(diào)用工具包的方式,特別適合用在程序自動(dòng)獲取報(bào)告的場(chǎng)景。

          注:其中977587123是數(shù)據(jù)庫(kù)的主機(jī)標(biāo)識(shí),可以在數(shù)據(jù)庫(kù)的數(shù)據(jù)字典中查到,1是標(biāo)識(shí)實(shí)例,如果是RAC,就有1和2兩個(gè),單機(jī)就只有1。SYSDATE-30/1440,SYSDATE-1/1440 分別是開始時(shí)間和結(jié)束時(shí)間。

          3ADDM的獲取與說明

          獲取ADDM報(bào)告的方式也有兩種,一種是直接獲取方式:調(diào)后臺(tái)腳本addmrpt.sql來獲取,執(zhí)行方式一般是在sqlplus下執(zhí)行@?/rdbms/admin/addmrpt.sql。另一種則是通過調(diào)用命令包的方式獲取:調(diào)用dbms_workload_repository這個(gè)包的addm_report_html程序。用SQL命令的形式輸出內(nèi)容。

          - Create an ADDM task.

          DBMS_ADVISOR.create_task (

          advisor_name=> 'ADDM',

          task_name=> 'MYADDM',

          task_desc=> 'MYADDM');

          (1)直接獲取

          @?/rdbms/admin/addmrpt.sql

          具體執(zhí)行過程略去。

          (2)通過調(diào)用命令包獲取

          注:直接調(diào)用工具包的方式,適合用在自動(dòng)獲取報(bào)告的場(chǎng)景。

          4AWRDD的獲取與說明

          獲取AWRDD報(bào)告一般是用直接獲取的方式,這個(gè)腳本的交互部分需要輸入要進(jìn)行對(duì)比的兩個(gè)awr報(bào)告的begin snap_id與end snap_id,然后輸入對(duì)比結(jié)果報(bào)告的名稱,這里就不詳細(xì)介紹了,請(qǐng)讀者自行試驗(yàn)完成。

          直接獲取:

          @?/rdbms/admin/awrddrpt.sql

          具體略去。

          5AWRSQ獲取與說明

          獲取AWRSQRPT報(bào)告的關(guān)鍵之處在于,交互部分要輸入所要分析的SQL的SQL_ID,這是關(guān)鍵之處。而這個(gè)SQL_ID可以從AWR報(bào)告中獲取。

          以上5個(gè)報(bào)告的獲取本身并不難,操作一遍就會(huì)了,筆者也會(huì)再提供在線操作視頻,讓大家實(shí)際體會(huì)一遍。現(xiàn)在關(guān)鍵在于,要明白這5個(gè)報(bào)告的作用和相互之間的區(qū)別,搞懂這些,調(diào)優(yōu)之路就算完成過半了。當(dāng)然,接下來如何分析讀懂這五大報(bào)告的關(guān)鍵指標(biāo)就非常重要了,有一些指標(biāo)你必須關(guān)注,否則你就當(dāng)不了“醫(yī)生”了。

          4、五大報(bào)告關(guān)注的要點(diǎn)1AWR的關(guān)注點(diǎn)

          AWR報(bào)告是五大報(bào)告中最全面最重要的一個(gè)報(bào)告,它的相關(guān)指標(biāo)也顯得格外重要。這里我們列出DB Time、load_profile、efficiency percentages、top 5 events、SQL Statistics、Segment_statistics這6個(gè)指標(biāo)入手分析。

          (1)AWR關(guān)注點(diǎn)1之DB Time

          DB Time這個(gè)指標(biāo)主要用來判斷當(dāng)前系統(tǒng)有沒有遇到相關(guān)瓶頸,是否較為繁忙導(dǎo)致等待時(shí)長(zhǎng)很長(zhǎng)。一般來說,Elapsed時(shí)間乘以CPU個(gè)數(shù)的時(shí)間如果結(jié)果大于DB Time,我們認(rèn)為系統(tǒng)壓力不大,反之則壓力較大。如下例子中,60.11×64=3847.04<5990.6,說明系統(tǒng)現(xiàn)在還是比較繁忙的。

          (2)AWR關(guān)注點(diǎn)2之load_profile

          load_profile這個(gè)指標(biāo)主要用來展現(xiàn)當(dāng)前系統(tǒng)的一些指示性能的總體參數(shù),比如經(jīng)典的Redo size就是用來顯示平均每秒的日志尺寸和平均每個(gè)事務(wù)的日志尺寸,結(jié)合Transactions這個(gè)每秒事務(wù)數(shù)的指標(biāo),就可以分析出當(dāng)前事務(wù)的繁忙程度。

          下圖中顯示每秒有6777.1個(gè)事務(wù)數(shù),這在現(xiàn)實(shí)中幾乎不可能,現(xiàn)實(shí)中的運(yùn)營(yíng)商系統(tǒng)一般在200上下比較正常,超過1000就屬于非常繁忙了。

          把上圖和下面的圖進(jìn)行比較,就非常明顯了,下圖顯示每秒有0.6個(gè)事務(wù),平均每個(gè)事務(wù)產(chǎn)生的日志尺寸是7位數(shù)。這說明系統(tǒng)是一個(gè)提交不頻繁的處理大任務(wù)事件的系統(tǒng)。而上圖的尺寸是3位數(shù)。這里非常容易看出,這是一個(gè)提交非常頻繁且每個(gè)事務(wù)都非常小的密集提交系統(tǒng)。

          (3)AWR關(guān)注點(diǎn)3之efficiency percentages

          efficiency percentages是一些命中率指標(biāo),其中Buffer Hit、Library Hit等都表示SGA(System global area)的命中率。在下圖中Soft Parse指標(biāo)表示共享池的軟解析率,在OLTP系統(tǒng)中如果該指標(biāo)低于90%應(yīng)當(dāng)引起你的注意,這表示存在未使用綁定變量的情況。我們通過比對(duì)兩個(gè)報(bào)告,可以看出明顯差異,如下面系列圖所示。

          報(bào)告1(未有效地使用綁定變量,產(chǎn)生大量硬解析的場(chǎng)景)。

          報(bào)告2(有效地使用綁定變量,進(jìn)行綁定變量?jī)?yōu)化后的場(chǎng)景)。

          (4)AWR關(guān)注點(diǎn)4之top 5 events

          等待事件是衡量數(shù)據(jù)庫(kù)整體優(yōu)化情況的重要指標(biāo),通過觀察Top 5 Timed Foreground Events模塊的Event和%DB time兩列,可以非常直觀地看出當(dāng)前數(shù)據(jù)庫(kù)面臨的主要等待事件是什么。下圖兩個(gè)例子分別告訴我們數(shù)據(jù)庫(kù)面臨鎖等待和日志切換等待的情形。

          (5)AWR關(guān)注點(diǎn)5 之SQL Statistics

          SQL Statistics分別從幾個(gè)維度來羅列出TOP的SQL,這是一種簡(jiǎn)單粗暴但有效的方法。看看執(zhí)行時(shí)長(zhǎng),直接拿出來優(yōu)化一般都是對(duì)的做法。

          (6)AWR關(guān)注點(diǎn)6 之Segment Statistics

          使用Segment Statistics指標(biāo)進(jìn)行尋找和判斷,也是一個(gè)非常直接的優(yōu)化手段。當(dāng)我們知道繁忙落在數(shù)據(jù)庫(kù)的那個(gè)表段是索引段時(shí),優(yōu)化就變得相對(duì)簡(jiǎn)單了,比如最簡(jiǎn)單粗暴的方法就是對(duì)表和索引進(jìn)行數(shù)據(jù)清理和瘦身。

          2ASH的關(guān)注點(diǎn)

          ASH是啥?哦,有人想起來了,胃鏡。

          完成了ASH報(bào)告的獲取后,打開獲得的ASH報(bào)告,其實(shí)對(duì)于該報(bào)告可關(guān)注的東西非常直接,就是看看哪些SQL和哪些等待事件是相關(guān)聯(lián)的。

          如下圖所示:

          3ADDM的關(guān)注點(diǎn)

          ADDM是啥?哦,是醫(yī)生的門診報(bào)告。

          由于這是Oracle的一些分析建議,所以ADDM的閱讀非常簡(jiǎn)單,基本上從FINDING 1、FINDING 2順序往下看就可以了。一般是從數(shù)據(jù)庫(kù)整體配置和局部SQL兩方面給出建議。我們看看都能明白,如下圖所示:

          整體性的建議

          局部SQL建議

          4AWRDD的關(guān)注點(diǎn)

          AWRDD是啥?哦,是醫(yī)生在看你前后兩次體檢報(bào)告,在比較指標(biāo)的變化。其實(shí)這個(gè)關(guān)注點(diǎn)很簡(jiǎn)單,基本上就是AWR關(guān)注什么,AWRDD就關(guān)注什么,沒什么特別的,簡(jiǎn)單列舉如下。

          (1)AWRDD關(guān)注點(diǎn)1 之不同時(shí)期load profile的比較

          (2)AWRDD關(guān)注點(diǎn)2 之不同時(shí)期等待事件的比較

          (3)AWRDD關(guān)注點(diǎn)3 之不同時(shí)期TOP SQL的比較

          5AWRSQRPT的關(guān)注點(diǎn)

          AWRSQRPT是啥?哦,有人想起來了,活檢。別打顫!

          其實(shí)沒啥,就是看看AWR和ASH里看不到的東西。都有啥呢?比如執(zhí)行計(jì)劃的相關(guān)細(xì)節(jié),關(guān)于執(zhí)行計(jì)劃我們會(huì)在后面詳細(xì)說明。這里要特別注意一點(diǎn),Oracle的執(zhí)行計(jì)劃可能會(huì)隨著環(huán)境的變化而變化,會(huì)隨著數(shù)據(jù)的變化而變化,因此可能會(huì)產(chǎn)生多個(gè)執(zhí)行計(jì)劃,這個(gè)AWRSQRPT就會(huì)出現(xiàn)多個(gè)執(zhí)行計(jì)劃。具體詳見下面系列圖。

          (1)Plan statistics

          (2)Execution Plan

          (3)是否有多個(gè)執(zhí)行計(jì)劃

          案例的分享與交流

          說了這么多,我們來看幾個(gè)相關(guān)案例,體會(huì)使用工具進(jìn)行整體優(yōu)化的重要性。

          1、和并行等待有關(guān)的案例

          這是來自某政府系統(tǒng)的一個(gè)平臺(tái)的案例,請(qǐng)看下圖,這是AWR報(bào)告的Top 5 Timed Events的展現(xiàn),可以看出當(dāng)前數(shù)據(jù)庫(kù)的等待事件主要是PX Deq相關(guān)的等待,這屬于濫用并行等待導(dǎo)致系統(tǒng)資源緊張的一個(gè)案例。

          該案例暴露出的問題比想象中更嚴(yán)重,因?yàn)樵撓到y(tǒng)的不少表和索引的屬性被設(shè)置了并行度,這導(dǎo)致所有對(duì)這些表和索引的訪問都成了并行訪問。后續(xù)解決思路就是將表和索引的并行屬性去掉。將一些需要并行處理的大任務(wù)進(jìn)行時(shí)間切割,確認(rèn)部分大任務(wù)是可以放在凌晨業(yè)務(wù)低峰期執(zhí)行的,就設(shè)置了并行的Hint任務(wù),讓部分SQL在夜間并行執(zhí)行,大部分SQL在白天正常執(zhí)行,從而系統(tǒng)恢復(fù)正常,業(yè)務(wù)也能順利開展。

          2、和熱塊競(jìng)爭(zhēng)有關(guān)的案例

          接下來我們?cè)倏匆粋€(gè)案例,這是某運(yùn)營(yíng)商的系統(tǒng),從AWR報(bào)告的Top 5 Timed Events等待事件主要是gc buffer busy來看,當(dāng)前系統(tǒng)主要等待事件是熱塊競(jìng)爭(zhēng)的等待。

          等待事件對(duì)應(yīng)的SQL主要有哪些,我們其實(shí)可以通過對(duì)應(yīng)時(shí)間段的ASH報(bào)告分析出來,比如下圖就是和AWR的對(duì)應(yīng)。

          將AWR報(bào)告和ASH報(bào)告結(jié)合起來看,往往可以找出具體需要優(yōu)化的SQL。在本案例中,我們發(fā)現(xiàn)兩個(gè)節(jié)點(diǎn)共同訪問一些對(duì)象導(dǎo)致熱塊競(jìng)爭(zhēng)。后續(xù)通過一系列改造,讓不同的業(yè)務(wù)跑在不同的節(jié)點(diǎn)上,從而避免了兩個(gè)節(jié)點(diǎn)訪問同一個(gè)對(duì)象,問題得以緩解。

          3、和日志等待有關(guān)的案例

          這是一個(gè)典型的案例,從Transactions達(dá)到800多,可以看出事務(wù)非常繁忙,再?gòu)腜er Transaction才1000左右,可以看出每個(gè)事務(wù)非常小。這說明了系統(tǒng)存在事務(wù)未批量提交的情況。這種情況一般出現(xiàn)在循環(huán)中,把提交寫到循環(huán)里面的情況。后續(xù)通過排查,發(fā)現(xiàn)果真是如此原因。

          接下來的log file switch(checkpoint incomplete) 和log file sync的相關(guān)等待正是由于日志切換過于頻繁導(dǎo)致的等待,這正是如前所述,未批量提交導(dǎo)致。

          4、新疆某系統(tǒng)的前臺(tái)優(yōu)化

          如下是新疆某運(yùn)營(yíng)商的優(yōu)化案例,我們通過Top 5 Timed Events等待事件發(fā)現(xiàn)了瓶頸主要在IO。接下來我們迅速到Tablespace IO Stats模塊去查看,如下圖所示:

          果然是有點(diǎn)問題。這個(gè)AV RD(MS)項(xiàng)表示平均一次物理讀花費(fèi)的時(shí)間(單位為ms)。有一種說法是, AV RD(MS)大于7就說明系統(tǒng)有嚴(yán)重的IO問題,其中BOSSWG_PERF_DATA居然達(dá)到了47,這說明當(dāng)前的存儲(chǔ)IO存在瓶頸。后續(xù)通過改善存儲(chǔ)解決了問題。

          5、浙江某系統(tǒng)的調(diào)優(yōu)案例

          這個(gè)案例來自浙江某生產(chǎn)系統(tǒng),我們通過Top 5 Timed Events等待事件發(fā)現(xiàn)了瓶頸主要在gc buffer busy等待事件,這和新疆某系統(tǒng)的前臺(tái)優(yōu)化案例類似。不過AWR報(bào)告非常強(qiáng)大,你通過各個(gè)細(xì)節(jié)都可以很有收獲,從而找到解決問題的方法,比如你此時(shí)直接定位到Segments by Global Cache Buffer Busy模塊,如下圖所示:

          通過觀察segments by global cache buffer busy的對(duì)象,我們找到了相關(guān)需要優(yōu)化的表。最后我們結(jié)合業(yè)務(wù),通過對(duì)該表瘦身、增加分區(qū)、避免兩個(gè)節(jié)點(diǎn)同時(shí)訪問的方案,優(yōu)化了對(duì)應(yīng)SQL的性能。

          總結(jié)

          End.

          來源:公眾號(hào)“DBAplus社群”

          運(yùn)行人員:中國(guó)統(tǒng)計(jì)網(wǎng)小編(微信號(hào):itongjilove)

          微博ID:中國(guó)統(tǒng)計(jì)網(wǎng)

          中國(guó)統(tǒng)計(jì)網(wǎng),是國(guó)內(nèi)最早的大數(shù)據(jù)學(xué)習(xí)網(wǎng)站,公眾號(hào):中國(guó)統(tǒng)計(jì)網(wǎng)

          http://www.itongji.cn

          AWR 是 Oracle 10g 版本 推出的新特性, 全稱叫Automatic Workload Repository-自動(dòng)負(fù)載信息庫(kù) AWR 是通過對(duì)比兩次快照(snapshot)收集到的統(tǒng)計(jì)信息,來生成報(bào)表數(shù)據(jù),生成的報(bào)表包括多個(gè)部分。

          前面已經(jīng)對(duì)awr報(bào)告的WORKLOAD REPOSITORY report部分做了介紹,下面根據(jù)生產(chǎn)環(huán)境對(duì)Report Summary部分的一些關(guān)鍵參數(shù)做分析,內(nèi)容比較多,大家盡量耐心看完,還是有點(diǎn)用的。


          cache sizes--內(nèi)存參數(shù)大小

          這里主要顯示SGA中每個(gè)區(qū)域的大小(在AMM改變它們之后),可用來與初始參數(shù)值比較。

          Buffer Cache:最終目的就是盡可能的減少磁盤I/O以便快速的讀或?qū)憽R膊皇窃酱笤胶茫绻鸅uffer Cache過大,會(huì)造成大的LRU 列表和 dirty list,引發(fā)邏輯讀的過程消耗CPU量高。同時(shí)大的Buffer Cache也會(huì)增加DBWn 進(jìn)程的負(fù)擔(dān)。

          shared pool主要包括library cache和dictionary cache。

          library cache用來存儲(chǔ)最近解析(或編譯)后SQL、PL/SQL和Java classes等。
          dictionary cache用來存儲(chǔ)最近引用的數(shù)據(jù)字典。
          

          發(fā)生在library cache或dictionary cache的cache miss代價(jià)要比發(fā)生在buffer cache的代價(jià)高得多。因此shared pool的設(shè)置要確保最近使用的數(shù)據(jù)都能被cache。

          我們可以看到shared pool一直收縮,在shrink過程中一些row cache 對(duì)象被lock住可能導(dǎo)致前臺(tái)row cache lock等解析等待,最好別讓shared pool shrink。如果這里shared pool一直在grow,那說明shared pool原有大小不足以滿足需求(可能是大量硬解析),結(jié)合后面的解析信息和SGA breakdown來一起診斷問題。

          Load Profile

          這里可以看到生產(chǎn)的硬解析每秒為102,硬解析為7.5,問題不大,但是Logons每秒3.3,表明可能有爭(zhēng)用問題,下面針對(duì)每個(gè)指標(biāo)具體分析:

          這里主要顯示數(shù)據(jù)庫(kù)負(fù)載概況,將之與基線數(shù)據(jù)比較才具有更多的意義,如果每秒或每事務(wù)的負(fù)載變化不大,說明應(yīng)用運(yùn)行比較穩(wěn)定。

          單個(gè)的報(bào)告數(shù)據(jù)只說明應(yīng)用的負(fù)載情況,絕大多數(shù)據(jù)并沒有一個(gè)所謂“正確”的值,Logons大于每秒1~2個(gè)、Hard parses大于每秒100、全部parses超過每秒300表明可能有爭(zhēng)用問題。

          Instance Efficiency Percentages (Target 100%)

          上述所有指標(biāo) 的目標(biāo)均為100%,即越大越好,在少數(shù)bug情況下可能超過100%或者為負(fù)值。

          80%以上 %Non-Parse CPU

          90%以上 Buffer Hit%, In-memory Sort%, Soft Parse%

          95%以上 Library Hit%, Redo Nowait%, Buffer Nowait%

          98%以上 Latch Hit%

          這里主要顯示Oracle關(guān)鍵指標(biāo)的內(nèi)存命中率及其它數(shù)據(jù)庫(kù)實(shí)例操作的效率。其中Buffer Hit Ratio 也稱Cache Hit Ratio,

          Library Hit ratio也稱Library Cache Hit ratio。

          在一個(gè)使用直接讀執(zhí)行大型并行查詢的DSS環(huán)境,20%的Buffer Hit Ratio是可以接受的,而這個(gè)值對(duì)于一個(gè)OLTP系統(tǒng)是完全不能接受的。

          根據(jù)多年的經(jīng)驗(yàn),對(duì)于OLTP系統(tǒng),Buffer Hit Ratio理想應(yīng)該在90%以上。

          Buffer Nowait表示在內(nèi)存獲得數(shù)據(jù)的未等待比例。在緩沖區(qū)中獲取Buffer的未等待比率

          Buffer Nowait的這個(gè)值一般需要大于99%。否則可能存在爭(zhēng)用

          buffer hit 高速緩存命中率,反應(yīng)物理讀和緩存命中間的糾結(jié),表示進(jìn)程從內(nèi)存中找到數(shù)據(jù)塊的比率,監(jiān)視這個(gè)值是否發(fā)生重大變化比這個(gè)值本身更重要

          Redo NoWait表示在LOG緩沖區(qū)獲得BUFFER的未等待比例。如果太低(可參考90%閥值),考慮增加LOG BUFFER。

          當(dāng)redo buffer達(dá)到1M時(shí),就需要寫到redo log文件,所以一般當(dāng)redo buffer設(shè)置超過1M,不太可能存在等待buffer空間分配的情況。

          library hit表示Oracle從Library Cache中檢索到一個(gè)解析過的SQL或PL/SQL語句的比率,當(dāng)應(yīng)用程序調(diào)用SQL或存儲(chǔ)過程時(shí),

          Oracle檢查L(zhǎng)ibrary Cache確定是否存在解析過的版本,如果存在,Oracle立即執(zhí)行語句;如果不存在,Oracle解析此語句,并在Library Cache中為它分配共享SQL區(qū)。

          Latch Hit:Latch是一種保護(hù)內(nèi)存結(jié)構(gòu)的鎖,可以認(rèn)為是SERVER進(jìn)程獲取訪問內(nèi)存數(shù)據(jù)結(jié)構(gòu)的許可。

          要確保Latch Hit>99%,否則意味著Shared Pool latch爭(zhēng)用,可能由于未共享的SQL,或者Library Cache太小,可使用綁定變更或調(diào)大Shared Pool解決。

          要確保>99%,否則存在嚴(yán)重的性能問題。

          Parse CPU to Parse Elapsd:解析實(shí)際運(yùn)行時(shí)間/(解析實(shí)際運(yùn)行時(shí)間+解析中等待資源時(shí)間),越高越好。即:解析實(shí)際運(yùn)行時(shí)間/(解析實(shí)際運(yùn)行時(shí)間+解析中等待資源時(shí)間)。如果該比率為100%,意味著CPU等待時(shí)間為0,沒有任何等待。

          Non-Parse CPU :SQL實(shí)際運(yùn)行時(shí)間/(SQL實(shí)際運(yùn)行時(shí)間+SQL解析時(shí)間),太低表示解析消耗時(shí)間過多。

          計(jì)算公式為:% Non-Parse CPU=round(100*1-PARSE_CPU/TOT_CPU),2)。如果這個(gè)值比較小,表示解析消耗的CPU時(shí)間過多。

          Soft Parse:軟解析的百分比(softs/softs+hards),近似當(dāng)作sql在共享區(qū)的命中率

          In-memory Sort:在內(nèi)存中排序的比率,如果過低說明有大量的排序在臨時(shí)表空間中進(jìn)行。

          Execute to Parse:是語句執(zhí)行與分析的比例,如果要SQL重用率高,則這個(gè)比例會(huì)很高。該值越高表示一次解析后被重復(fù)執(zhí)行的次數(shù)越多。

          Shared Pool Statistics

          Memory Usage %:對(duì)于一個(gè)已經(jīng)運(yùn)行一段時(shí)間的數(shù)據(jù)庫(kù)來說,共享池內(nèi)存使用率,應(yīng)該穩(wěn)定在75%-90%間,

          如果太小,說明Shared Pool有浪費(fèi),而如果高于90,說明共享池中有爭(zhēng)用,內(nèi)存不足。

          這個(gè)數(shù)字應(yīng)該長(zhǎng)時(shí)間穩(wěn)定在75%~90%。如果這個(gè)百分比太低,表明共享池設(shè)置過大,帶來額外的管理上的負(fù)擔(dān),從而在某些條件下會(huì)導(dǎo)致性能的下降。如果這個(gè)百分率太高,會(huì)使共享池外部的組件老化,如果SQL語句被再次執(zhí)行,這將使得SQL語句被硬解析。這里顯示生產(chǎn)環(huán)境比率低于75%,沒有充分利用shared pool。

          SQL with executions>1:執(zhí)行次數(shù)大于1的sql比率,如果此值太小,說明需要在應(yīng)用中更多使用綁定變量,避免過多SQL解析。

          在一個(gè)趨向于循環(huán)運(yùn)行的系統(tǒng)中,必須認(rèn)真考慮這個(gè)數(shù)字。在這個(gè)循環(huán)系統(tǒng)中,在一天中相對(duì)于另一部分時(shí)間的部分時(shí)間里執(zhí)行了一組不同的SQL語句。

          在共享池中,在觀察期間將有一組未被執(zhí)行過的SQL語句,這僅僅是因?yàn)橐獔?zhí)行它們的語句在觀察期間沒有運(yùn)行。只有系統(tǒng)連續(xù)運(yùn)行相同的SQL語句組,這個(gè)數(shù)字才會(huì)接近100%。

          Memory for SQL w/exec>1:執(zhí)行次數(shù)大于1的SQL消耗內(nèi)存的占比。

          這是與不頻繁使用的SQL語句相比,頻繁使用的SQL語句消耗內(nèi)存多少的一個(gè)度量。

          這個(gè)數(shù)字將在總體上與% SQL with executions>1非常接近,除非有某些查詢?nèi)蝿?wù)消耗的內(nèi)存沒有規(guī)律。

          在穩(wěn)定狀態(tài)下,總體上會(huì)看見隨著時(shí)間的推移大約有75%~85%的共享池被使用。如果Statspack報(bào)表的時(shí)間窗口足夠大到覆蓋所有的周期,

          執(zhí)行次數(shù)大于一次的SQL語句的百分率應(yīng)該接近于100%。這是一個(gè)受觀察之間持續(xù)時(shí)間影響的統(tǒng)計(jì)數(shù)字。可以期望它隨觀察之間的時(shí)間長(zhǎng)度增大而增大。


          總結(jié):通過ORACLE的實(shí)例有效性統(tǒng)計(jì)數(shù)據(jù),我們可以獲得大概的一個(gè)整體印象,但是不能由此來確定數(shù)據(jù)運(yùn)行的性能。當(dāng)前性能問題的確定,我們主要還是依靠后面介紹的等待事件來確認(rèn)。

          可以這樣理解兩部分的內(nèi)容,hit統(tǒng)計(jì)幫助我們發(fā)現(xiàn)和預(yù)測(cè)一些系統(tǒng)將要產(chǎn)生的性能問題,這樣可以做到未雨綢繆。而wait事件,就是表明當(dāng)前數(shù)據(jù)庫(kù)已經(jīng)出現(xiàn)了性能問題需要解決,所以是亡羊補(bǔ)牢的性質(zhì)。

          后面會(huì)分享更多DBA方面的內(nèi)容,感興趣的朋友可以關(guān)注下!!


          主站蜘蛛池模板: 动漫精品一区二区三区3d| 一区二区三区国产精品| 国产av一区最新精品| 精品一区二区三区四区在线播放 | 无码国产精品一区二区免费16| 国产成人高清精品一区二区三区| 日韩免费无码视频一区二区三区| 伊人久久大香线蕉av一区| 国产高清一区二区三区四区| 动漫精品第一区二区三区| 精品一区二区三区3d动漫| 国产福利电影一区二区三区久久老子无码午夜伦不 | 亚洲AV日韩综合一区| 国产视频一区二区| 日韩人妻无码一区二区三区 | 亚洲AV无码一区二区三区牲色| 韩国精品一区二区三区无码视频| 无码人妻一区二区三区在线水卜樱| 精品一区二区久久| 日韩精品人妻一区二区三区四区 | 中文无码一区二区不卡αv| 精品一区二区高清在线观看| 国产精华液一区二区区别大吗| 无码播放一区二区三区| 黑人一区二区三区中文字幕| 国产成人AV一区二区三区无码| 日韩在线一区二区三区视频| 美女啪啪一区二区三区| 国产精品一区二区三区高清在线| 精品国产一区二区三区免费| 在线|一区二区三区| 国产美女精品一区二区三区| 另类ts人妖一区二区三区| 夜夜添无码一区二区三区| 国产一区韩国女主播| 亚洲一区二区三区久久久久| 国精品无码A区一区二区| 韩国女主播一区二区| 无码人妻一区二区三区一| 精品一区二区三区四区| 一区二区三区杨幂在线观看|