【问题标题】:Improving performance of EXTRACTVALUE in WHERE clause提高 WHERE 子句中 EXTRACTVALUE 的性能
【发布时间】:2013-05-21 11:10:50
【问题描述】:

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

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

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

EXTRACTVALUE在这样的select语句中使用时

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

只需要 0.5 秒。

body 列是 CLOB 类型。

【问题讨论】:

  • 第一个查询可能在选择列表中包含 CLOB,而第二个查询只有一个列可供选择。如果将星号替换为“EXTRACTVALUE(xmltype(body),'/Event/Description/Status')”(如在第二个查询中),第一个查询需要多长时间?你的 CLOB 有多大?
  • 如果我按照你说的那样替换它,结果是一样的(甚至更长一点)。我的 CLOB 很不一样,有的有 600 行,有的有 10000 行,但是选择 Status 值很快,所以我没想到按那个过滤会增加执行时间。

标签: sql xml performance oracle plsql


【解决方案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;

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

【讨论】:

    【解决方案2】:

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

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

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

    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';
    

    【讨论】:

      猜你喜欢
      • 2014-12-27
      • 2021-05-16
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-12
      相关资源
      最近更新 更多