如何識別最耗資源的SQL

一般來說,調優的第一手資料,很可能就是典型業務期的一個statspack報告,那麼如何根據statspack報告來判斷是哪些SQL消耗了最多的系統資源?哪些SQL是最需要調整的呢?這裏給出了一個大致的優化思路。當然,思路是死的,人是活的,優化也需要隨需應變。

一般來說,需要關注下面四種Top SQL

  • 消耗最多CPU的(邏輯IO過多)
  • 導致過多物理I/O的
  • 執行次數較頻繁的
  • 執行時間較長的

我們知道,一個語句的響應時間有個很著名的公式:

響應時間=服務時間+等待時間

其中服務時間就是CPU爲執行該語句花費的時間。

服務時間=分析時間+遞歸時間+執行時間

分析時間是CPU用於分析語句的時間,遞歸時間是CPU用於語句的遞歸SQL的時間,剩下的則就是CPU用於執行語句的真正時間了。

那麼,上面的這些時間信息從哪裏來的?Oracle提供的系統統計信息中就有部分的時間統計信息:

服務時間=CPU used by this session
分析時間=parse time cpu
遞歸時間=recursive cpu usage

那麼,執行時間就可以根據上面三個統計信息計算得出:

執行時間=CPU used by this session - parse time cpu - recursive cpu usage

  • 如果執行時間在整個響應時間中佔較大的比例,那麼下一步就是找出那些造成了最多邏輯IO的SQL語句,可以從statspack報告的SQL ordered by Gets部分找到。
  • 如果分析時間在整個響應時間中佔較大的比例,那麼下一步就是查找哪些SQL分析過多,這在statspack報告中在SQL ordered by Parse Calls中列出。
  • 如果等待時間在整個響應時間中佔較大的比例,並且主要是塊讀取相關的等待時,下一步就是找出哪些SQL造成了過多的物理讀,可以查看statspack報告中的SQL ordered by Reads部分。

那麼,根據上面列出的一個簡單的原則,我們需要關注三個關於CPU時間的統計信息: CPU used by this session, parse time cpu和recursive cpu usage,以及top5等待事件中和IO相關的等待時間。如果是其他的一些等待事件出現在Top5中,那麼可能需要根據不同的等待事件來分析原因了。然後優先調優時間消耗最多的相關SQL。

除了上面的SQL ordered by Gets(邏輯IO最多),SQL ordered by Parse Calls(軟解析過多),SQL ordered by Reads(物理IO過多),statspack還按照其他的一些方式列出了Top SQL,這些Top SQL在某些情況下都是需要給予特別關注的。比如

  • SQL ordered by Executions 執行次數超過100的
  • SQL ordered by Sharable Memory 佔用library cache超過1M的
  • SQL ordered by Version Count 子cursor超過20的

如果沒有statspack,那麼根據v$sysstat/v$sesstat中的統計信息,結合v$sql/v$sqlarea,一樣可以得到相關的SQL。

v$sql對於每一個子cursor都有一行統計記錄,而v$sqlarea則對同一個父cursor只有一行統計記錄,也就是v$sqlarea是對v$sql按照父cursor進行group by後的一個結果。這兩個視圖中都有諸如buffer_gets,parse_calls,disk_reads,,executions,sharable_mem等列,和上面提到的statspack中列出Top SQL的條件對應。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章