SQL執行計劃之sql_trace

一,sql_trace的做用:用以描述SQL的執行過程的trace輸出。html

     - SQL是如何操做數據的
     - SQL執行過程當中產生了哪些等待事件
     - SQL執行中消耗了多少資源
     - SQL的實際執行計劃
     - SQL產生的遞歸語句
 
二,set autotrace 與 sql_trace的區別
     set autotrace用於輸出優化器產生的執行計劃,執行計劃展現的資源消耗狀況是CBO的估算值,並不必定是SQL實際執行時資源消耗狀況。好比,向表t中插入10萬條數據,執行查詢的時候發現只返回少許數據,這可能就是表t尚未被Oracle重分析,它並不知道表的數據已更新。
     sql_trace是SQL實際的執行狀況。
 
三,什麼時候使用set autotrace 與 sql_trace
     當須要分析執行計劃及CBO行爲時,使用set autotrace;當要看一條SQL的真實運行效果時,使用sql_trace。
 
四,sql_trace的使用
     (1)收集本回話的SQL執行過程
     SQL>alter session set sql_trace=true
      SQL>alter session set statistics_level = all;          
     SQL>alter session set timed_statistics = true;          
     SQL>alter session set max_dump_file_size = unlimited;
     SQL>alter session set tracefile_identifier = liangjian
     SQL>sql.....
     SQL>alter session set sql_trace=false
     SQL>exit                         
 
     (2)收集其它會話的SQL執行過程
     SQL1>select sid, serial# from v$session;                                                            
     SQL2>execute  dbms_system.set_sql_trace_in_session(sid, serial#, true);           
     SQL2>sql....
     SQL2>execute  dbms_system.set_sql_trace_in_session(sid, serial#, false); 
 
五,trace文件內容
     生成的trace文件的目錄由參數文件指定,能夠經過v$diag_info視圖來查看,name=Default Trace File的值就是trace文件的默認路徑。下面是一個實際生成的trace文件:
  
      trace文件內容:
  
     trace文件中記錄的是Oracle按照時間前後順序來輸出的,它是Oracle執行SQL最底層的過程。上面第二個紅色方框中體現的就是咱們所發出SQL執行的過程,其意思是:首先打開一個標號爲4的遊標,關聯這條SQL語句,而後解析這條SQL語句(PARSE #4),其中mis=1表示共享區中沒有可共享已解析SQL,故它執行的是一次硬解析,而後執行SQL語句,再而後獲取數據,最後關閉遊標。有時候遊標標號相同的輸出並不在一塊兒,由於trace文件是按照時間的前後順序輸出的,這也最能反映Oracle內部的執行順序。
 
     trace文件中有不少鍵值對信息,初次看trace文件也必定是看不懂的,下面介紹一下各個鍵所表明的含義:
     

六,tkprof格式化工具
     trace文件並不直觀,爲了讓讀者一目瞭然,Oracle提供了格式化trace文件的工具:tkprof
(1)tkprof命令
     Usage: tkprof tracefile outputfile [explain= ] [table= ] [print= ] [insert= ] [sys= ] [sort= ]
     參數說明
      tracefile:你要分析的trace文件的絕對路徑
      outputfile:格式化後的文件絕對路徑
      explain=user/password@connectstring,對每條SQL 語句肯定其執行規劃,並將執行規劃寫到輸出文件中。若是不是有explain,在trace文件中咱們看到的是SQL實際的執行路徑,不會有sql的執行計劃(能夠對比實際執行規劃和執行計劃的差異)
     table=schema.tablename,在輸出到輸出文件前,用於存放臨時表的用戶名和表名。
     PRINT:只列出輸出文件的最初N個SQL語句。默認爲全部的SQL語句。
      AGGREGATE:若是= NO,則不對多個相同的SQL進行彙總。若是爲yes則對trace文件中的相同sql進行合併。
     INSERT:SQL 語句的一種,用於將跟蹤文件的統計信息存儲到數據庫中。在TKPROF建立腳本後,在將結果輸入到數據庫中。
      SYS:若是設置爲yes,則全部sys用戶的操做(也包含用戶sql語句引起的遞歸sql),這樣能夠減小分析出來的文件的複雜度,便於查看。
     sort:對trace文件的sql語句根據須要排序,其中比較有用的一個排序選項是fchela,即按照elapsed time fetching來對分析的結果排序(記住要設置初始化參數timed_statistics=true),生成的文件將把最消耗時間的sql放在最前面顯示。
 
     執行計劃分爲兩部分,第一部分稱爲行源操做(Row Source Operation ),是遊標關閉且開啓跟蹤狀況下寫到跟蹤文件中的執行計劃。這意味着若是應用程序不關閉遊標而重用它們的話,不會有新的針對重用遊標的執行計劃寫入到跟蹤文件中。第二部分,叫作執行計劃 (Execution Plan),是由指定了explain參數的TKPROF生成的。既然這是隨後生成的,因此和第一部分不必定徹底匹配。萬一看到二者不一致,前者是正確的。兩個執行計劃都經過Rows列提供執行計劃中每一個操做返回的行數(不是處理的--要注意)。 對於每一個行源操做來講,可能還會提供以下的運行時統計: 
     cr是一致性模式下邏輯讀出的數據塊數。
     pr是從磁盤物理讀出的數據塊數。
     pw是物理寫入磁盤的數據塊數。
     time是以微秒錶示的總的消逝時間。要注意根據統計獲得的值不老是精確的。實際上,爲了減小開銷,可能用了採樣。
     cost是操做的評估開銷。這個值只有在Oracle 11g才提供。
     size是操做返回的預估數據量(字節數)。這個值只有在Oracle 11g才提供。 
     card是操做返回的預估行數。這個值只有在Oracle 11g才提供。 
 
     輸出文件的結尾給出了全部關於跟蹤文件的信息。首先能夠看到跟蹤文件名稱、版本號、用於這個分析所使用的參數sort的值。而後,給出了全部會話數量與SQL語句數量。 
     Optimizer mode: ALL_ROWS表示優化器採用的是all_rows的模式
     Parsing user id: 55 表示用戶id爲55 
 
 
(2)格式化後輸出文件的解釋
     首先解釋輸出文件中列的含義:
     CALL:每次SQL語句的處理都分紅三個部分
     Parse:這步將SQL語句轉換成執行計劃,包括檢查是否有正確的受權和所須要用到的表、列以及其餘引用到的對象是否存在。
     Execute:這步是真正的由Oracle來執行語句。對於insert、update、delete操做,這步會修改數據,對於select操做,這步就只是肯定選擇的記錄。
     Fetch:返回查詢語句中所得到的記錄,這步只有select語句會被執行。
     COUNT:這個語句被parse、execute、fetch的次數。
     CPU:這個語句對於全部的parse、execute、fetch所消耗的cpu的時間,以秒爲單位。
     ELAPSED:這個語句全部消耗在parse、execute、fetch的總的時間。
     DISK:從磁盤上的數據文件中物理讀取的塊的數量。
     QUERY:在一致性讀模式下,全部parse、execute、fetch所得到的buffer的數量。一致性模式的buffer是用於給一個長時間運行的事務提供一個一致性讀的快照,緩存實際上在頭部存儲了狀態。
     CURRENT:在current模式下所得到的buffer的數量。通常在current模式下執行insert、update、delete操做都會獲取buffer。在current模式下若是在高速緩存區發現有新的緩存足夠給當前的事務使用,則這些buffer都會被讀入了緩存區中。
     ROWS: 全部SQL語句返回的記錄數目,可是不包括子查詢中返回的記錄數目。對於select語句,返回記錄是在fetch這步,對於insert、update、delete操做,返回記錄則是在execute這步。
 
(3)trace文件中的性能分析 
     一、若是分析數與執行數之比爲1,說明每次執行這個查詢都要進行sql解析。若是分析數與執行數之比接近0,則意味着查詢執行了不少次軟解析,下降了系統的可伸縮性。
     二、若是trace文件中顯示對全部或者幾乎全部的sql都執行一次,那有多是由於沒有正確使用綁定變量。
     三、若是一個(Fetch Count)/所得到行數的比值接近1,且行數大於1,則應用程序不執行大批量取數操做,每種語言/API都有能力完成這個功能,即一次取多行。若是沒有利用這個功能進行批量去,將有可能花費多得多的時間在客戶端與服務器端之間來回往返。這個過多的來回轉換出了產生很擁擠的網絡情況以外,也會比一次調用得到不少行要慢得多,如何指示應用程序進行批量獲取將隨語言/API而定。
     四、若是CPU時間與elasped時間有巨大差別,意味着有可能花了大量時間在等待某些事情上。若是花了一個CPU時間來執行,但它卻總共花了10秒的時間,這就意味着90%的運行時間在等待一個資源。例如被一個會話等待,或者大量查詢時的物理IO等待等
     五、較長的CPU或通過時間每每是最消耗資源的sql,須要咱們關注
     六、能夠經過磁盤IO所佔邏輯IO的比例,disk/query+current來判斷磁盤IO的狀況,太大的話有多是db_buffer_size太小,固然這也跟SQL的具體特性有關
     七、query+current/rows 平均每行所需的block數,太大的話(超過20)SQL語句效率過低,數據過於分散,能夠考慮重組對象
 
相關文章
相關標籤/搜索