4

有没有可能提高这个查询在 PL/SQL 中的性能?

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

when EXTRACTVALUEis inWHERE子句,整个查询执行 15 秒,肯定太长了。

什么时候EXTRACTVALUE在这样的选择语句中使用

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

仅需0.5秒。

body是 CLOB 类型。

4

2 回答 2

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';
于 2013-05-26T20:34:12.117 回答
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;

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

于 2013-05-26T14:25:52.467 回答