Более эффективный способ использования цикла курсора, вставки в и фиксации для каждой строки (Oracle)

#loops #cursor #commit #bulk-collect

#циклы #курсор #фиксировать #массовый сбор

Вопрос:

Я написал что-то подобное ниже (это работает), но в моем случае для 1,5 миллионов строк это не так эффективно, как мне нужно (это продлится, возможно, 2 дня) Я видел что-то вроде МАССОВОЙ ВЫБОРКИ ДЛЯ ВСЕХ и т.д. Но мне не удается переписать свой код для этого без ошибок. Можете ли вы помочь мне с этим?

Спасибо

 --It is my code for rewriting
    DECLARE
      cnt NUMBER;
      d_min NUMBER;
      d_max NUMBER;
      i NUMBER := 0;
      CURSOR ts_metatata_cur IS select * from (select rownum as rn, id_profile from ts_metadata where typ=7 and per=3600 order by id_profile) where rn between 1 and 100000;
    BEGIN
      for metadata_rec in ts_metatata_cur
      LOOP
            XTS.GET_PROFILE_AGGR(metadata_rec.id_profile, cnt, d_min, d_max);    --procedure with one IN parameter and three OUT parameter cnt, d_min, d_max
            Execute immediate 'insert into TMP_PROFILES_OVERVIEW (id_profile, cnt, d_min, d_max) values (' || metadata_rec.id_profile || ', ' || cnt || ', ' || d_min ||  ', ' || d_max ||')';
            i := i 1;
            if (i > 10000) then
              commit;
              i := 0;
            end if;
      END LOOP;
    commit;
    END;
  

Если это необходимо, я привожу здесь процедуру, которую я вызываю:

 --this is procedure, which I call in my script
CREATE OR REPLACE PROCEDURE XTS.GET_PROFILE_AGGR(id_prof IN NUMBER, cnt OUT NUMBER, d_min OUT NUMBER, d_max OUT NUMBER)
AS 
  res varchar2(61);
BEGIN
  select cluster_table_name into res FROM XTS.TIME_SERIES TS where TS.id=id_prof;
  Execute immediate 'select nvl(count(*),0), nvl(min(time),0), nvl(max(time),0) from '|| res || ' where time_series_id=' || id_prof || ' ' into cnt, d_min, d_max;

EXCEPTION

  when others then
  null;

END;
  

Ответ №1:

Я изменил свой подход к задаче после советов других людей. Я ВСТАВЛЯЮ только сгруппированные данные вместо ВСТАВКИ В каждую строку.

Что-то вроде этого:

СОЗДАЙТЕ ИЛИ ЗАМЕНИТЕ ПРОЦЕДУРУ XTS.GET_PROFILE_AGGR
В
качестве time_series_cur КУРСОРА, выбрав в качестве res из xts.time_series отдельное имя кластерной таблицы;

 BEGIN  
  for time_series_rec in time_series_cur  
  LOOP  
    Execute immediate 'INSERT INTO HDO.tmp_profiles_overview (id_profile, cnt, d_min, d_max) select time_series_id, count(*), min(time), max(time) from ' || time_series_rec.res || ' group by time_series_id';  

  END LOOP;  

commit;   
END;