使用IN子句中的子查询,Oracle性能降低

时间:2016-02-22 15:39:08

标签: sql xml database oracle subquery

我有这样的查询:

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 个答案:

答案 0 :(得分: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;

N.B。未经测试,由于缺乏样本数据。

好的,以下是什么给你的?

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

另一个建议是将/*+ dynamic_sampling(xdata 10) */替换为/* cardinality(xdata <roughly expected number of rows>) */(当然会覆盖相关数字)。

此外,您是否可以编辑您的问题以提供包含和不包含硬编码变量的查询的执行计划?