【问题标题】:Speed of INSERT INTO插入速度
【发布时间】:2016-06-25 18:58:17
【问题描述】:

我有一个用于将记录从一个表移动到另一个表的工作过程:

create or replace procedure p_insert_sdpcenroll
  as 

  v_rec_cnt number := 0;

  cursor c_de_data is
    select a.term
      ,a.report_date
      ,a.report_type
      ,a.metric_num
      ,a.metric
      ,a.total
 from sdpcenroll_stg a;

 type de_table is table of c_de_data%rowtype index by binary_integer;
 t_de_table de_table;

begin

open c_de_data;

loop

  fetch c_de_data bulk collect
    into t_de_table limit 100;

  exit when t_de_table.count = 0;  

    forall de_rec in 1..t_de_table.count
      --insert into sdpcenroll (term, report_date, report_type, metric_num, metric, total)
      insert into (select a.term
                         ,a.report_date
                         ,a.report_type
                         ,a.metric_num
                         ,a.metric
                         ,a.total
                   from sdpcenroll a)
        values (t_de_table(de_rec).term
               ,t_de_table(de_rec).report_date
               ,t_de_table(de_rec).report_type
               ,t_de_table(de_rec).metric_num
               ,decode(t_de_table(de_rec).metric_num, '9', 'TS_GPC_Total (unduplicated)', t_de_table(de_rec).metric)
               ,t_de_table(de_rec).total)
          log errors into err$_sdpcenroll reject limit unlimited;

      v_rec_cnt := v_rec_cnt + sql%rowcount;

end loop;

close c_de_data;

dbms_output.put_line(v_rec_cnt||' total rows inserted.');  

delete from sdpcenroll_stg;
dbms_output.put_line(sql%rowcount||' staging rows deleted.');

exception
  when others then
    raise_application_error(-20100, 'Processing error occurred. Check log table for error records. '||sqlcode||' - '||sqlerrm);                 

end p_insert_sdpcenroll;

对于大约 50 万条记录,该过程在大约 27 秒内运行。但是,如果我用注释掉的 INSERT INTO 代码替换我正在使用的 INSERT INTO 代码,则该过程始终会减慢到大约 34 秒。

INSERT INTO table (columns) 本质上是否比INSERT INTO (SELECT columns FROM table) 慢,或者这只是在这个特定过程中出现的一个怪癖?

【问题讨论】:

    标签: sql oracle plsql insert procedure


    【解决方案1】:

    我不知道通过匿名视图插入是否比INSERT...(column list)... 快。

    但是,鉴于您显示的代码,没有必要将数据读入内存然后将其写回。相反,您可以使用INSERT...SELECT... 构造,如

    create or replace procedure p_insert_sdpcenroll   as 
    BEGIN
      INSERT INTO (SELECT TERM,
                          REPORT_DATE,
                          REPORT_TYPE,
                          METRIC_NUM,
                          METRIC,
                          TOTAL
                     FROM SDPCENROLL)
      SELECT TERM
             REPORT_DATE
             REPORT_TYPE
             METRIC_NUM
             DECODE(METRIC_NUM,
                      '9', 'TS_GPC_Total (unduplicated)', 
                           METRIC),
             TOTAL
        FROM SDPCENROLL_STG
        log errors into err$_sdpcenroll
        reject limit unlimited;
    
      dbms_output.put_line(SQL%ROWCOUNT||' total rows inserted.');  
    
      delete from sdpcenroll_stg;
      dbms_output.put_line(sql%rowcount||' staging rows deleted.');
    exception
      when others then
        raise_application_error(-20100, 'Processing error occurred. Check log table for error records. '||sqlcode||' - '||sqlerrm);                 
    end p_insert_sdpcenroll;
    

    祝你好运。

    【讨论】:

    • 哇。这段代码比我使用的要快三到四倍。看来我还有很多东西要学。谢谢。
    猜你喜欢
    • 2016-08-14
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多