Oracle
休眠查詢執行緩慢
我目前正面臨從 Java 程序啟動的執行緩慢的 Hibernate 查詢的問題。它正在後端呼叫 Oracle 11g。
此查詢在第一次執行時需要 40-90 秒。然而,在隨後的執行中,查詢會在很短的時間內返回(而且我什至沒有看到數據庫被命中,所以假設 hibernate 正在記憶體它)。
如果我將查詢從企業管理器複製並粘貼到 SQL 客戶端並直接執行相同的查詢(甚至更改一些參數),查詢會在幾分之一秒內返回。
如果我查看 EM 中的性能調整選項卡,我發現所花費的時間主要用於使用者 I/O 等待 (97.5%) 和 CPU (2.5%)。這是否意味著我在休眠中使用的獲取大小配置的值太小了?
如果您可能需要任何其他資訊來幫助我深入了解此問題,請告訴我。
=====
附加資訊:
我們在表上有一個索引,我可以看到它被用作查詢執行的一部分,不幸的是它不是很可讀,但我不確定如何包含它:
Id Operation Name Rows (Estim) Cost Time Active(s) Start Active Execs Rows (Actual) Read Reqs Read Bytes Mem (Max) Activity (%) Activity Detail (# samples) 0 SELECT STATEMENT 1 1 . FILTER 1 2 .. HASH JOIN RIGHT OUTER 2674 7223 1 +4 1 0 1M 3 ... TABLE ACCESS FULL TOTEM_EQ_EXPIRYCODES 475 4 1 +4 1 481 4 ... HASH JOIN RIGHT OUTER 2674 7219 1 +4 1 0 399K 5 .... TABLE ACCESS BY INDEX ROWID TOTEM_EQ_UNDERLYINGS 1 2 1 +4 1 1 6 ..... INDEX UNIQUE SCAN TOTEM_EQ_UND_PK 1 1 1 +4 1 1 7 .... NESTED LOOPS 1 8 ..... NESTED LOOPS 2674 7216 42 +4 1 0 9 ...... TABLE ACCESS BY GLOBAL INDEX ROWID EQUITIES_MONTHLY_INSTRUMENTS 2671 1871 45 +1 1 8438 3517 27MB 24.44 db file sequential read (11) 10 ....... INDEX RANGE SCAN EQ_MON_INS_UNDERLYING_INDX 2671 12 42 +4 1 8438 27 216KB 11 ...... PARTITION RANGE ITERATOR 1 2 8438 12 ....... INDEX RANGE SCAN EQ_MON_RESULT_INSPT_UNQ 1 2 44 +2 8438 0 5403 42MB 75.56 Cpu (1) db file sequential read (33) 13 ..... TABLE ACCESS BY LOCAL INDEX ROWID EQUITIES_MONTHLY_RESULTS 1 3 Here are the Global stats: Elapsed Time(s) Cpu Time(s) IO Waits(s) Fetch Calls Buffer Gets Read Reqs Read Bytes 45 0.73 45 1 22980 9740 76MB
事實證明,問題與被選為查詢計劃一部分的索引有關。
該查詢接受一個範圍作為其參數集的一部分。由於我現在不討論的原因,我們將範圍開始日期和結束日期傳遞為相同的值。
當我們直接進行呼叫時,我們對這些參數進行硬編碼,Oracle 推斷它們代表一個日期,而當通過程式碼傳遞它們時,範圍作為綁定變數傳遞。
這意味著 Oracle 選擇在一種情況下掃描所有分區,在另一種情況下掃描特定分區。
我們最終通過僅傳遞一個日期參數來修復查詢,因為我們意識到我們不需要範圍!
誠然,這是一個相當特殊的情況!