Oracle

休眠查詢執行緩慢

  • May 7, 2015

我目前正面臨從 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 選擇在一種情況下掃描所有分區,在另一種情況下掃描特定分區。

我們最終通過僅傳遞一個日期參數來修復查詢,因為我們意識到我們不需要範圍!

誠然,這是一個相當特殊的情況!

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