Вставка 7000000 записей

km
Дата: 29.09.2004 15:21:08
Всем привет !

Подскажите пожалуйста как грамотно реализовать следующую задачу:
Надо перенести значения 2-х столбцов из одной таблицы в другую, причем в новой таблице есть констрейнт, проверяющий уникальность комбинаци из этих 2-х полей.
Данные находятся в таблице:
CREATE TABLE CARD (
ISSUE_ID NUMBER (4) NOT NULL,
ID VARCHAR2 (10) NOT NULL,
CABINET_PWD VARCHAR2 (44),
PIN_CODE VARCHAR2 (44)
...
CONSTRAINT PK_CARD
PRIMARY KEY ( ISSUE_ID, ID ) ..);

Записей ~7000000

переносятся в таблицу:
CREATE TABLE CARD_STORAGE (
PIN1 VARCHAR2 (44) NOT NULL,
PIN2 VARCHAR2 (44) NOT NULL,
CONSTRAINT CARD_STORAGE_UNIQUE
UNIQUE (PIN1, PIN2) USING INDEX ..);

делаю так :
SET TRANSACTION USE ROLLBACK SEGMENT RBL01;

DECLARE
cont    INTEGER;
CURSOR cCard IS SELECT issue_id, id, cabinet_pwd, pin_code FROM CARD;
-- тут пробовал ограничивать набор данных выбираемых в курсор, но разницы практически нет
BEGIN
    cont := 1;
     FOR vCard IN cCard LOOP       
        BEGIN
            INSERT INTO CARD_STORAGE (PIN1, PIN2) 
                                         VALUES ( vCard.cabinet_pwd, vCard.pin_code);

            IF cont = 10000 THEN
                COMMIT;
                cont := 1;
            ELSE
                cont := cont + 1;
            END IF;              
        EXCEPTION 
            WHEN DUP_VAL_ON_INDEX THEN
               dbms_output.put_line('Found duplicate: '|| vCard.issue_id ||'-'||                vCard.id);      
        END;
    END LOOP;
    COMMIT;        
EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line('Exception: '||SQLCODE||':'||SQLERRM);
END;

Проблемма при такой реализации в том, что работает данный процесс очень медленно , 100000 записей вносятся ~10-15 мин. При этом с экземпляром идет интенсивная работа и все текущие активные сессии начинают становиться в очередь и обслуживаются долго, что вызывает недовольство клиентов...

Как вообще решаются такие задачи ?

Заранее благодарен!
ScareCrow
Дата: 29.09.2004 15:26:10
навскидку... батч из нескольких инсертов в теле цикла.....
Vadim_Maximov
Дата: 29.09.2004 15:27:04
Как вариант:
INSERT --+ APPEND 
INTO CARD_STORAGE (PIN1, PIN2) 
AS 
SELECT field 1, 
       field2 
FROM   уникальный список записей
km
Дата: 29.09.2004 15:30:09
ScareCrow
навскидку... батч из нескольких инсертов в теле цикла.....

простите а батч это что ?
Oleg Afanasiev
Дата: 29.09.2004 15:30:10
может лучше удалить дубликаты а после
с insert /* append */ .... nologging ?
в цикле в любом случае будет долго
Barkovsky
Дата: 29.09.2004 15:31:04
отключить констрейнт на время - возможно?
km
Дата: 29.09.2004 15:32:11
Vadim_Maximov
Как вариант:
INSERT --+ APPEND 
INTO CARD_STORAGE (PIN1, PIN2) 
AS 
SELECT field 1, 
       field2 
FROM   уникальный список записей


так пробовал, только без hint-a... разницы нет :(
km
Дата: 29.09.2004 15:33:56
2> Oleg Afanasiev может лучше удалить дубликаты а после
Из родительской таблицы выностить ничего нельзя категорически, там дубликатов будет очень не много 5-6 штук.
Vadim_Maximov
Дата: 29.09.2004 15:35:48
Oleg Afanasiev
может лучше удалить дубликаты а после
с insert /* append */ .... nologging ?
в цикле в любом случае будет долго

Попробуй так, с хинтом & nologging.
Только нужно понимать, что данная операция будет unrecoverable.
Vadim_Maximov
Дата: 29.09.2004 15:37:14
Да, и дубликаты исключи в запросе, не удаляя записи из "родительской" таблицы.