2015-03-10 4 views
1

Есть ли способ ускорить этот кусок кода?Есть ли способ ускорить следующие вставки (-ы)?

FOR j IN 1..max 
LOOP 
    INSERT INTO myTable VALUES(DBMS_RANDOM.VALUE(1, 500), DBMS_RANDOM.VALUE(1, 500)); 
END LOOP; 

Цикл будет происходить не менее миллиона раз, поэтому миллион + вставки. Я знаю о FORALL, но это для коллекций данных, которые уже существуют .. не очень полезно для меня. Поэтому мне было интересно, есть ли лучший способ, чем классический цикл или, по крайней мере, некоторые другие улучшения, которые я могу сделать (например, добавление/удаление некоторых параметров при создании таблицы), все, что может ускорить этот запуск.

Заранее благодарен!

+0

Пробуйте различные размеры транзакций? – jarlh

+0

Сколько времени требуется, чтобы запустить его и сколько вы хотите ускорить? –

+0

Немного лучше, если использовать локальную 'переменную' для' DBMS_RANDOM.VALUE (1, 500) ', а затем использовать ее;). –

ответ

10

Вы можете попробовать использовать один оператор вставки вместо выполнения инструкции в миллион раз:

insert into myTable 
    select 
    dbms_random.value(1, 500), 
    dbms_random.value(1, 500) 
    from 
    dual 
    connect by 
    level <= 1*1000*1000; 

На стороне записки: вы измерить, сколько времени тратится на выполнение dbms_random и сколько время на Фактически Вставка значений?

+0

Спасибо большое! Ваше решение действительно помогло! – districktt

5

Миллион строк, вставленных во время одной транзакции, будет использовать много места в вашем табличном пространстве UNDO. Лучшим выбором ИМО является использование некоторых промежуточных коммитов для сокращения диапазона транзакций. Таким образом, опираясь на @ ответ ReneNyffenegger, я предлагаю что-то вроде следующего:

DECLARE 
    nRows_inserted NUMBER := 0; 
BEGIN 
    FOR i IN 1..1000 LOOP 
    INSERT INTO MY_TABLE 
     SELECT DBMS_RANDOM.VALUE(1, 500), 
      DBMS_RANDOM.VALUE(1, 500) 
     FROM DUAL 
     CONNECT BY LEVEL <= 1000; 

    nRows_inserted := nRows_inserted + SQL%ROWCOUNT; 

    COMMIT; 
    END LOOP; 

    DBMS_OUTPUT.PUT_LINE(nRows_inserted || ' rows inserted into MY_TABLE'); 
END; 

Делите и наслаждайтесь.

+0

+1: Хотя, 1000 кажется очень маленьким для такой узкой вставки (2 поля). OP должен играть с этим значением, пока не увидит уменьшающуюся отдачу :) – MatBailie

+0

На 1000 математике проще ... хотя я все еще пытаюсь подсчитать все мои пальцы ... :-) –

+0

Большое спасибо за не торопитесь ответить! – districktt

Смежные вопросы