Хранимая процедура занимает слишком много времени, есть ли лучший способ сделать это / оптимизировать? - PullRequest
0 голосов
/ 29 августа 2018

В настоящее время я пытаюсь массово вставить большой объем данных (~ 500 000 строк) по ссылке в базе данных. Я беру данные из Материализованных Представлений. Я собирался добавить индексы, но где-то читал, что это на самом деле замедлит процесс. После того, как я вставляю строки, я беру уникальные идентификаторы и вставляю их в таблицу маркировки, чтобы они были помечены как «вставленные» и больше не вставлялись. Однако этот процесс застрял на 30 минут. Есть лучший способ сделать это? (Ниже мой код).

create or replace PROCEDURE   SEND_DATA
IS
   CURSOR cursora
   IS
      SELECT DISTINCT unique_id_1
        FROM mv_1;

   CURSOR cursorb
   IS 
      SELECT DISTINCT unique_id_2
       FROM mv_2;

ca cursora%ROWTYPE;
cb cursorb%ROWTYPE;

    sent_flag NUMBER(10);
BEGIN
    SELECT flag_id
     INTO sent_flag
     FROM flag f
    WHERE f.flag_tx = 'SENT';
---
Delete FROM TABLE1@db1
      WHERE to_date(to_char(LOCAL_TIMESTAMP,'mm/dd/yyyy'),'mm/dd/yyyy') || code in 
 (SELECT distinct to_date(to_char(LOCAL_TIME_TS,'mm/dd/yyyy'),'mm/dd/yyyy'), code FROM MV_1);
COMMIT;
    Delete FROM TABLE1@db1 
          WHERE type || timestamp in (SELECT DATA_Type_TX || UTC_TS FROM MV_1);
    COMMIT;
    insert into TABLE1@db1(DATE, TYPE, VALUE, LAST_UPDATE, FLAG, LOCAL_TIMESTAMP)
    SELECT DATA_DATE,  NAME, VALUE, SYSDATE, null, LOCAL_TIME
  FROM MV_2 A;

COMMIT;
OPEN cursora;

LOOP
 FETCH cursora into ra;
 EXIT WHEN cursora%NOTFOUND;
 INSERT INTO flag(
    SUBMIT_ID,
    FLAG_ID,
    CREATE_USER_ID,
         CREATE_DT)
   VALUES (
    rdba.SUBMIT_ID,
    SENT_FLAG,
    '1',
         sysdate);
END LOOP;
CLOSE cursora;
COMMIT;
---
EXCEPTION
      WHEN OTHERS
      THEN
           NULL;
       RAISE;
    END SEND_DATA;

1 Ответ

0 голосов
/ 30 августа 2018

В вашей процедуре есть несколько недостатков, на самом деле она должна завершиться неудачей.

create or replace PROCEDURE   SEND_DATA IS
   CURSOR cursora IS
      SELECT DISTINCT unique_id_1
        FROM mv_1;

   CURSOR cursorb IS 
      SELECT DISTINCT unique_id_2
       FROM mv_2;

Курсор cursorb не используется в процедуре, почему вы объявляете это?

Delete FROM TABLE1@db1
      WHERE to_date(to_char(LOCAL_TIMESTAMP,'mm/dd/yyyy'),'mm/dd/yyyy') || code in 
 (SELECT distinct to_date(to_char(LOCAL_TIME_TS,'mm/dd/yyyy'),'mm/dd/yyyy'), code FROM MV_1);

Это должно закончиться неудачей, потому что сначала вы объединяете два столбца, но в IN () вы выбираете два столбца. В любом случае, удалите предложение DISTINCT - это бесполезно.

    Delete FROM TABLE1@db1 
          WHERE type || timestamp in (SELECT DATA_Type_TX || UTC_TS FROM MV_1);

Не следует использовать зарезервированные ключевые слова, такие как TIMESTAMP, в качестве имени столбца.

LOOP
 FETCH cursora into ra;
 EXIT WHEN cursora%NOTFOUND;
 INSERT INTO flag(SUBMIT_ID, FLAG_ID, CREATE_USER_ID, CREATE_DT)
   VALUES ( rdba.SUBMIT_ID, SENT_FLAG, '1', sysdate);
END LOOP;

Почему вы заключаете числовые значения в кавычки (т.е. '1')? Этот код также должен давать сбой, потому что переменные ra и rdba не объявлены. Я предполагаю, что это было

LOOP
 FETCH cursora into ca;
 EXIT WHEN cursora%NOTFOUND;
 INSERT INTO flag(SUBMIT_ID, FLAG_ID, CREATE_USER_ID, CREATE_DT)
   VALUES ( ca.unique_id_1, SENT_FLAG, '1', sysdate);
END LOOP;

Перепишите это как

INSERT INTO flag (SUBMIT_ID, FLAG_ID, CREATE_USER_ID, CREATE_DT)
SELECT DISTINCT unique_id_1, SENT_FLAG, 1, sysdate
FROM mv_1;

Если предположить, что выше будет представлена ​​правильная логика

EXCEPTION
      WHEN OTHERS
      THEN
           NULL;
       RAISE;

Эта часть совершенно бесполезна. WHEN OTHERS THEN NULL; означает «игнорировать любую ошибку», но в следующем ряду вы ее поднимаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...