首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >优化Oracle 11g过程

优化Oracle 11g过程
EN

Stack Overflow用户
提问于 2011-12-31 00:02:12
回答 3查看 693关注 0票数 2

我有一个过程来查找一个非常大的表中的一系列交易的第一,最后,最高和最低价格,这是由日期,对象名称和代码组织的。我还需要成交数量的总和。表中大约有30亿行,这个过程需要很多天才能运行。我想尽可能地缩短这段时间。我在trans表中的不同字段上有一个索引,查看查询的select部分的explain计划,就会发现正在使用该索引。我对另一种方法的建议持开放态度。我使用Oracle11g R2。谢谢。

代码语言:javascript
复制
    declare
    cursor c_iter is select distinct dt, obj, cd from trans;
    r_iter c_iter%ROWTYPE;
    v_fir number(15,8);
    v_las number(15,8);
    v_max number(15,8);
    v_min number(15,8);
    v_tot number;
    begin
    open c_iter;
    loop
        fetch c_iter into r_iter;
        exit when c_iter%NOTFOUND;

      select max(fir), max(las) into v_fir, v_las 
      from 
            ( select 
                first_value(prc) over (order by seq) as "FIR",
                first_value(prc) over (order by seq desc) as "LAS"
              from trans
              where dt = r_iter.DT and obj = r_iter.OBJ and cd = r_iter.CD );

            select max(prc), min(prc), sum(qty) into v_max, v_min, v_tot
            from trans
            where dt = r_iter.DT and obj = r_iter.OBJ and cd = r_iter.CD;

            insert into stats (obj, dt, cd, fir, las, max, min, tot )
            values (r_iter.OBJ, r_iter.DT, r_iter.CD, v_fir, v_las, v_max, v_min, v_tot);

            commit;
    end loop;
    close c_iter;
end;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-12-31 01:02:28

代码语言:javascript
复制
alter session enable parallel dml;

insert /*+ append parallel(stats)*/
into stats(obj, dt, cd, fir, las, max, min, tot)
select /*+ parallel(trans) */ obj, dt, cd
    ,max(prc) keep (dense_rank first order by seq) fir
    ,max(prc) keep (dense_rank first order by seq desc) las
    ,max(prc) max, min(prc) min, sum(qty) tot
from trans
group by obj, dt, cd;

commit;

  • 单个SQL语句通常比多个SQL语句快得多。它们有时需要更多的资源,例如更多的临时表空间,但是您的distinct游标可能已经在对磁盘上的整个表进行排序。
  • 您可能还希望启用并行DML和并行查询,不过,根据对象和系统设置的不同,这种情况可能已经发生。(这并不一定是一件好事,这取决于您的资源,但它通常有助于大型queries.)
  • Parallel写和追加应该可以提高性能,如果SQL写入大量数据,但这也意味着新表将无法恢复,直到下一次备份。(并行DML将自动使用直接路径写入,但我通常会包括APPEND,以防并行性不能正常工作。)

即使对于这么小的查询,也有很多需要考虑的地方,但这就是我要开始的地方。

票数 7
EN

Stack Overflow用户

发布于 2011-12-31 00:14:59

这不是我想给出的可靠答案,但有几件事需要考虑:

第一种方法是使用bulk collect。但是,由于您使用的是11g,希望已经自动为您完成了这项工作。

你真的需要在每次迭代后提交吗?我可能错了,但我猜这是你的顶级消费者之一。

最后,jonearles的答案是+1。(我不确定是否能够将所有内容都写到一个SQL查询中,但我也建议这样做。)

票数 2
EN

Stack Overflow用户

发布于 2011-12-31 00:43:18

您可以尝试使查询并行运行,在此here上有一份合理的Oracle白皮书。这不是我曾经使用过的Oracle特性,所以我没有第一手的经验来传递它。您还需要在Oracle服务器上有足够的可用资源,以允许您运行将创建的并行进程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8681368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档