如何在Oracle SQL Developer中执行超过一百万个插入查询?

时间:2018-10-16 11:07:22

标签: sql oracle oracle-sqldeveloper sql-scripts

我有超过一百万个插入查询要在Oracle SQL Developer中执行,这需要很多时间。有什么办法可以对此进行优化。

5 个答案:

答案 0 :(得分:8)

SQL Developer是错误的工具,无法运行1,000,000行按行插入。

SQL * Plus也是如此。

如果您无法编写使用循环或游标进行插入的程序,或者某些pl / sql批量收集,则do what @marmite-bomber suggests-将您的数据写到平面分隔的文本文件中,并设置一个SQL * Loader方案。

Now, you CAN use SQL Developer to do this.

enter image description here

指向分隔的文本文件。

向上映射所有内容,然后使用此IMPORT方法。 enter image description here

完成后,您将需要执行一组bash或cmd脚本。但是首先,您的计算机上需要一个Oracle客户端-sqlldr程序所在的位置。

它比运行1,000,000个单独的刀片快几个数量级。而且您的DBA不会讨厌您。

使用SQLDev向导,您可以在短短几分钟内启动并运行它。

证明: 我测试了一个简单的场景-我的发现是(details here): SQL * Loader每秒插入10,753条记录 每秒为SQL Developer插入342条记录

SQL * Loader的速度提高了3144%。

答案 1 :(得分:2)

运行单行INSERT s对于这样的行数是不可行的。

所以一种可能的方法是预处理脚本,仅提取CSV数据。

这是一个简单的例子

Insert into TAB(COL1,COL2,COL3) values ('1','xxx',to_date('16-10-2018 15:13:49','DD-MM-YYYY HH24:MI:SS'));
Insert into TAB(COL1,COL2,COL3) values ('2','zzzzz',to_date('06-10-2018 15:13:49','DD-MM-YYYY HH24:MI:SS'));

删除所有不相关的部分

'1','xxx','16-10-2018 15:13:49'
'2','zzzzz','06-10-2018 15:13:49'

并使用SQL * Loader或外部表加载此文件。表现会很好。

答案 2 :(得分:0)

  

我有超过一百万个插入查询要在Oracle SQL Developer中执行

执行任何SQL语句都会产生开销。您要支付该税1000000倍。另外,某些IDE会为工作表中执行的每条SQL语句的结果实例化一个单独的选项卡(单击运行时)。我不记得SQL Developer是否这样做,但是如果这样做,那又是另一笔税,您要支付100万次。

两种可能的优化方式。

通过从dual中选择值,将单行插入片段转换为集合操作:

insert into your_table
select blah_seq.nextval, q.txt, q.val from (
   select 'WHATEVER' as txt, 42 as val from dual union all
   select 'AND SO ON'  as txt, 23 as val  from dual union all
    ...
);

这将减少开销。为此,需要进行大量的编辑工作。

或者,使用大容量加载选项(例如SQL * Loader或外部表)加载数据。如果您有支持正则表达式的程序员编辑器(例如Notepad ++),则剥离insert语法并将values子句转换为CSV行相对简单。

第三种方法是回到产生百万插入语句的源头,并要求它们以更易于管理的格式提供数据,例如数据泵导出。

答案 3 :(得分:0)

另一个建议是进行验证,确认可能的PK列上没有任何重复。插入之前先删除约束,然后再放回去。保持该备用脚本方便。您可以将其作为同一脚本或不同脚本的一部分来执行。同样,如果您不检查是否有重复,则将PK重新设置为期望错误;那么您将使用dups跟踪行并删除该数据。

答案 4 :(得分:0)

您可以将数据块放入集合并批量插入

此外,删除除主键以外的所有索引。数据加载后创建索引

可能有点危险,但是根据数据的质量,您还可以删除外键,然后在导入数据后重新创建它们。您必须确保您的导入不会破坏FK关系

declare
    type my_tab is table of mytable%rowtype index by binary_integer;
    a_imp   my_tab;
begin

    -- do stuff to populate a_imp from presumably a text file? or select statement

    -- you could chunk your population of the array and bulk insert say 10,000 rows at a time

    -- loop through the holding array and import any remaining data
    forall ix in 1 .. a_imp.count
        insert into [tabel_name] values a_imp(ix);
    commit;

end;