2016-02-22 65 views
1

我有這樣的查詢性能下降:甲骨文使用子查詢中IN子句

SELECT 
    xmlelement("objects", 
    xmlagg(
     xmlelement("object", 
      xmlelement("accountId", ACCOUNTS.accountId), 
      xmlelement("address", ACCOUNTS.ADDRESS) 
    ) 
    ) 
    INTO obj_info_xml 
    FROM 
     ACCOUNTS 
    WHERE account_code IN (SELECT EXTRACTVALUE(VALUE(accountCodes), '/accountCode/text()') as accountCode 
       FROM TABLE(XMLSEQUENCE(EXTRACT(X, '//accountCodes/accountCode'))) accountCodes); 

當我硬編碼值內部IN條款,然後查詢執行速度快,但是當我使用子查詢從XML選擇那麼我就不能獲得結果,因爲它執行得非常慢。你有什麼建議嗎?

+1

幾個建議......有些發誓用EXISTS代替IN會提供性能上的優勢,但它有多大的改進值得懷疑 - 仍然是一個簡單的嘗試。但是,我認爲可能會有更多幫助,因爲子查詢使用子查詢因子分解(使用WITH語句)。然後,解析器將決定是否要像內嵌視圖那樣處理查詢,或者是否想要創建臨時表來存儲這些值。無論哪種方式,你應該看到性能增益。請閱讀以下有關子查詢因子分析的信息:https://oracle-base.com/articles/misc/with-clause – DanK

+0

這是在將RDBMS用作XML的數據存儲而不是RDBMS時發生的情況。 –

+0

不確定您使用的是哪個版本,但是您是否使用[XML索引](http://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb_indexing.htm#ADXDB0500)進行了查看。如果XPATH查找是瓶頸,這應該有助於加快速度。 – ruudvan

回答

0

假設x是包含了您的帳戶代碼列表中,這樣的事情應該加快速度一點點PL/SQL變量:

select xmlelement("objects", 
        xmlagg(xmlelement("object", 
            xmlelement("accountId", accounts.accountid), 
            xmlelement("address", accounts.address)) 
         ) 
       ) account_xml 
into obj_info_xml 
from accounts a 
     inner join xmltable('//accountCodes/accountCode' 
          passing x 
          columns account_code varchar2(30) path '.') xdata -- amend datatype as appropriate 
     on a.account_code = xdata.account_code; 

注:未經測試,由於缺乏樣本數據。


好的,下面給你什麼?

select xmlelement("objects", 
        xmlagg(xmlelement("object", 
            xmlelement("accountId", accounts.accountid), 
            xmlelement("address", accounts.address)) 
         ) 
       ) account_xml 
into obj_info_xml 
from accounts a 
where a.account_code in (select /*+ dynamic_sampling(xdata 10) */ 
           account_code 
          from xmltable('//accountCodes/accountCode' 
              passing x 
              columns account_code varchar2(30) path '.') xdata); -- amend datatype as appropriate 

另一個建議將與/* cardinality(xdata <roughly expected number of rows>) */(與相關數重寫當然)取代/*+ dynamic_sampling(xdata 10) */

另外,你可以編輯你的問題,提供執行計劃的查詢有和沒有硬編碼變量,請?

+0

感謝您的建議,但這也是緩慢的,因爲我的原始查詢 – user2412672

+0

我已經用一些可能有用的建議更新了我的答案。 – Boneist