首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >INSERT-SELECT (Oracle PL/SQL) -性能问题

INSERT-SELECT (Oracle PL/SQL) -性能问题
EN

Stack Overflow用户
提问于 2017-08-21 19:21:31
回答 2查看 1.8K关注 0票数 1

我有太多的SELECT语句,而只有一个INSERT语句(可能有数百个),系统的性能很差。

我将用一般的语言解释正在发生的事情和我正在寻找的东西:

考虑到Oracle PL/SQL中的以下两个伪代码,它们中的哪一个将提供最佳性能?

选项A:

代码语言:javascript
复制
INSERT INTO MyTable
  WITH Fields AS (
     SELECT Field1, Field2, ..., FieldN FROM TableA JOIN TableW .... WHERE <condition1>
     UNION ALL
     SELECT Field1, Field2, ..., FieldN FROM TableB JOIN TableX .... WHERE <condition2>
     UNION ALL
     SELECT Field1, Field2, ..., FieldN FROM TableC JOIN TableB .... WHERE <condition3>
     ....
     UNION ALL
     ....
     SELECT Field1, Field2, ..., FieldN FROM TableZZZ JOIN TableB .... WHERE <conditionN>

选项B:

代码语言:javascript
复制
BEGIN
  INSERT INTO MyTable SELECT Field1, Field2, ..., FieldN FROM TableA JOIN TableZ .... WHERE <condition1>
  INSERT INTO MyTable SELECT Field1, Field2, ..., FieldN FROM TableB JOIN TableW .... WHERE <condition2>
  INSERT INTO MyTable SELECT Field1, Field2, ..., FieldN FROM TableC JOIN TableH .... WHERE <condition3>
  ...
  INSERT INTO MyTable SELECT Field1, Field2, ..., FieldN FROM TableZZZZ JOIN TableX .... WHERE <conditionN>
END

我没有放入真实的表名,但我想知道:如果我将当前的选项A更改为选项B,它会给我带来更好的性能吗?我的意思是,在这种情况下,用许多INSERT语句替换UNION ALL是个好主意吗?

EN

回答 2

Stack Overflow用户

发布于 2017-08-21 19:39:47

上下文切换和Performance

几乎PL/SQL开发人员编写的每个程序都包含PL/SQL和SQL语句。PL/SQL语句由PL/SQL语句执行器运行;SQL语句由SQL语句执行器运行。当PL/SQL运行时引擎遇到SQL语句时,它会停止并将该SQL语句传递给SQL引擎。SQL引擎执行SQL语句并将信息返回给PL/SQL引擎(参见图1)。这种控制转移称为上下文切换,每个切换都会产生开销,从而降低程序的整体性能。

因此,使用第三种方法:

代码语言:javascript
复制
create view MyView as select Field1, Field2, ..., FieldN from TableA join TableB .... where <condition1>

declare
  p_array_size pls_integer := 100;
  type         array is table of MyView%rowtype;
  l_data       array;
  cursor c is select * from MyView;    
begin
    open c;
    loop
    fetch c bulk collect into l_data limit p_array_size;

    forall i in 1..l_data.count
    insert into MyTable values l_data(i);

    exit when c%notfound;
    end loop;
    close c;
end;
票数 2
EN

Stack Overflow用户

发布于 2017-08-21 20:38:32

除非您的查询在数据库服务器上的内存方面非常特殊,否则选项B不会提高大型查询的性能。

要确保上述情况属实,请尝试让您的DBA在执行查询时检查数据库服务器SGA中发生的情况。如果内存中出现阻塞,那么值得尝试实现选项B

当我说“内存阻塞”时,我的意思是整个SGA内存已满,因此需要在服务器上进行交换。如果在序列中执行插入操作,则可以在插入操作之间重用SGA。

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

https://stackoverflow.com/questions/45795826

复制
相关文章

相似问题

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