Oracle

oracle查詢第二次比較慢

  • August 9, 2018

我有一個關於我在 Oracle 的性能調整中看到的一般性問題。我有一個正在測試的查詢。我無法提供一個簡單的例子,它太大太複雜了,對不起!(我嘗試降低它,但失去了症狀)

我第一次執行查詢時,是 2 秒。隨後的時間是 3、4 甚至 5 秒。這種情況始終如一地發生 - 如果我改變間距,我會再次獲得 2 秒,然後它會恢復。

這與我的預期相反——在第一次之後,數據庫不需要解析查詢,並且應該將塊讀入緩衝區記憶體。我唯一能想到的是它正在某處寫入臨時數據,以這種方式寫入和讀取它比讀取它更快。但這當然沒有意義。

有誰知道為什麼會這樣?或者執行計劃中的任何危險信號會導致這樣的事情?

僅供參考,這是一個 SELECT,具有多個連接、聚合和視圖。沒有內部 PL/SQL。

謝謝

@Colin 另一個程序不太可能影響這台開發機器,至少如此一致。不確定什麼是動態採樣。與基數回饋相同嗎?

@druzin 沒有綁定變數,但也沒有謂詞更改 - 相同的雜湊。

@mustaccio 好主意,儘管我懷疑這與隱式臨時表或記憶體有關。我會試一試。

這種情況通常可以通過啟用跟踪事件 10046(如果您有權這樣做)來解決,並在生成的跟踪文件上執行 tkprof:

alter session set events '10046 trace name context forever, level 8';
select /* try one */ -- add your SQL here and invoke it;
select /* try two */ -- add your same SQL here and invoke it;
show parameter user_dump_destination

呼叫它幾次,然後關閉跟踪,註銷以確保關閉跟踪文件:

alter session set events '10046 trace name context off';
exit;

然後找到您的跟踪文件,並在其上執行 tkprof,假設您的跟踪文件名為${ORACLE_SID}_ora_39110.trc

cd $ORACLE_BASE/diag/rdbms/$ORACLE_SID/$ORACLE_SID/trace
tkprof ${ORACLE_SID}_ora_39110.trc ${ORACLE_SID}_ora_39110.trc.txt
vi ${ORACLE_SID}_ora_39110.trc.txt

tkprof 的輸出將顯示執行統計資訊(邏輯讀取、物理讀取等)。如果 tkprof 輸出沒有幫助,您可以查看實際的跟踪文件。

如果這沒有幫助,您可以啟用 10053 事件,並享受在數千行輸出中的樂趣;但有時你需要這樣做。

但首先要做的事情(更容易的事情)首先;按照別人的建議去做;查看表統計資訊是否是最新的、優化器設置等。如果您每次執行都使用完全相同的標準,則優化器可能在計劃中處於“邊界”。我會確保你已經收集了系統統計數據;請參閱dbms_stats.gather_system_stats pl/sql 包的文件。

我會看一些東西:

  • CURSOR_SHARING=EXACT 和 CURSOR_SHARING=FORCE 之間是否存在性能差異。
  • 查看此 SQL_ID 的等待事件。
select
   event,
   time_waited "time_waited(s)",
   case when time_waited = 0 then 
       0
   else
       round(time_waited*100 / sum(time_waited) Over(), 2)
   end "percentage"
from
   (
       select event, sum(time_waited) time_waited
       from v$active_session_history
       where sql_id = 'SQL_ID'
       group by event
   )
order by
   time_waited desc;

引用自:https://dba.stackexchange.com/questions/50594