提高WHERE子句中EXTRACTVALUE的性能

时间:2013-05-26 11:41:22

标签: sql xml performance oracle plsql

是否有可能在PL / SQL中提高此查询的性能?

SELECT * FROM events 
WHERE EXTRACTVALUE(xmltype(body),'/Event/Description/Status') = 'Cancelled'

EXTRACTVALUEWHERE子句中时,整个查询执行15秒,肯定太长了。

在select语句中使用EXTRACTVALUE

SELECT EXTRACTVALUE(xmltype(body),'/Event/Description/Status') FROM events

只需0.5秒。

body是CLOB类型。

2 个答案:

答案 0 :(得分:3)

WHERE子句中的函数速度不慢。但是,如果您的IDE仅返回前N行,则可能会出现这种情况。

您可以使用基于函数的索引来提高性能。

这是示例表和数据。 1000行中只有一行包含状态“已取消”,这使其成为索引的良好候选者。

create table events(id number primary key, body clob);

insert into events
select level,
    '<Event>
        <Description>
            <Status>'||
            case when mod(level, 1000) = 0 then 'Cancelled' else 'Active' end||
            '</Status>
        </Description>  
    </Event>'
from dual connect by level <= 10000;

commit;

begin
    dbms_stats.gather_table_stats(user, 'EVENTS');
end;
/

查询需要3秒钟才能执行全表扫描。

SELECT * FROM events 
WHERE EXTRACTVALUE(xmltype(body),'/Event/Description/Status') = 'Cancelled';

创建索引更改会将计划更改为INDEX RANGE SCAN,并减少 时间到0.03秒。

create index events_fbi on events
    (extractValue(xmltype(body), '/Event/Description/Status'));

SELECT * FROM events 
WHERE EXTRACTVALUE(xmltype(body),'/Event/Description/Status') = 'Cancelled';

答案 1 :(得分:1)

您可以尝试构建物化视图:

create view x as
  select
      e.*, 
      EXTRACTVALUE(xmltype(body),'/Event/Description/Status')  status
    FROM events e;

create materialized view x2 as select * from x;

然后从物化视图中选择。为了加快速度,您可以在状态列上添加索引。