2016-07-28 18 views
1

我在Oracle BBDD中遇到問題。一個查詢會消耗大量的SGA,直到BBDD開始給出錯誤ORA-04031並且我不得不重置它。SQL高可用內存

在AWR中,我可以看到「可共享內存中排序的SQL」中的查詢。查詢出現在此部分大量的時間,一個由每個不同的 「或的」,例如:

查詢1:

...My Query... WHERE (inc.ID =:"SYS_B_131" 
    OR inc.ID     =:"SYS_B_132" 
    OR inc.ID     =:"SYS_B_133" 
    OR inc.ID     =:"SYS_B_134") 

問題2:

...My Query... WHERE (inc.ID =:"SYS_B_131" 
    OR inc.ID     =:"SYS_B_132" 
    OR inc.ID     =:"SYS_B_133" 
    OR inc.ID     =:"SYS_B_134" 
    OR inc.ID     =:"SYS_B_135" 
    OR inc.ID     =:"SYS_B_136" 
    OR inc.ID     =:"SYS_B_137" 
    OR inc.ID     =:"SYS_B_138") 

等,等

我的問題是,具有4「或」項目的查詢具有3MB的內存消耗,具有500個「或」項目的查詢具有1GB的內存消耗,這是正常的嗎?

+1

你使用cursor_sharing設置爲類似還是強制?最好的解決方案是強制應用程序使用綁定變量。 – ibre5041

+0

是的,光標共享設置爲「FORCE」。 – Ildelian

+0

不要使用CURSOR_SHARING = FORCE作爲永久修復。默認是CURSOR_SHARING = EXACT – pahariayogi

回答

1

我找到了問題。是一個Oracle錯誤。在我的Oracle BBDD版本中,如果查詢有很多綁定變量,查詢執行計劃會消耗大量的SGA(僅在查詢時爲1.2Gb)。

我已經重寫了查詢,用SubQuery替換「IN」值列表,並且問題解決了。

0

我不會說它是一個錯誤。這是Oracle設置的一個相當明智的限制,其目的是爲了防止一個查詢塞滿大部分珍貴的SGA內存。 應用500「IN」列表謂詞根本不建議練習(帶或不帶綁定)。而且,僅僅在子查詢中推送500個「IN」列表謂詞在這裏將無濟於事。 我們應該所有的這些500點多元的ID存儲在一張小桌子和索引FK和應用EXISTS子查詢像 -

SELECT <col list> FROM MainTable inc 
WHERE EXISTS (SELECT 1 FROM 500_IDTable inc2 inc.ID = inc2.ID); 

雖然你沒有共享修改後的查詢/子查詢,這是你必須做的事情,我猜。

@ ibre5041 - 以上發佈的查詢已經使用bind var。實際上,綁定變量太多了。

Ildelian - 我們絕不應該使用CURSOR_SHARING = FORCE作爲永久修復。應該使用'精確'代替。默認是CURSOR_SHARING = EXACT。

瞭解爲什麼https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:4608916500346512056

採用CURSOR_SHARING =力量在他們的庫緩存已經顯示出與文字困擾數據庫的好處(即非重入SQL)。

在你的情況,CURSOR_SHARING = FORCE沒有任何意義,因爲你似乎已經使用綁定變量。

請考慮更改CURSOR_SHARING = EXACT。