Добавление большого объема данных

 
0
 
Oracle
ava
Plamenk | 15.06.2005, 10:22
Всем Привет!

Я создал хранимки выполняющиее примерно такой запрос:

INSERT INTO table1 (...)
SELECT ... FROM table2

Данная комманда добавляет примерно 200000 записей! Время выполнения при этом составляет порядка от 20 мин до много (в зависимости от table1 и table2).

Вопрос собственно в том, какие есть средства или операторы, чтобы заставить Oracle делать это быстрее. (Т.е. объяснить Oracle, что сейчас будет пакетное добавление).

(Про индексы и тригеры я знаю!)

Заранее БОЛЬШОЕ СПАСИБО!

Comments (11)
ava
Dimich | 15.06.2005, 12:33 #
Могу посоветовать применить копирование таблицы коммандой COPY.

copy from user/[email protected] to user/[email protected] create table1 using select * from table2;


Можете почитать тут: http://www.oracleutilities.com/SQLPLus/copy.html
ava
Dimich | 15.06.2005, 15:30 #
Кстати, можно еще попробовать хинт /*+ APPEND NOLOGGING */
чтобы не использовать сегменты отката и сравнить....
ava
Plamenk | 15.06.2005, 16:03 #
Спасибо, Dimich !

Только я в ХП не особо силен мог бы ты привести простенькие примерски как использовать /*+ APPEND NOLOGGING */!
Мне кажется это должно помочь!
ava
igon | 16.06.2005, 00:16 #

create or replace
procedure test is
begin
begin
Execute Immediate 'DROP Table test_table';
Exception When Others Then Null;
End;
begin
dbms_output.put_line(to_char(Sysdate,'mi:ss'));
Execute Immediate 'Create table test_table as select * from source_table';
dbms_output.put_line(to_char(Sysdate,'mi:ss'));
Insert /*+ APPEND NOLOGGING */ Into test_table select * from source_table;
dbms_output.put_line(to_char(Sysdate,'mi:ss'));
Commit;
Insert Into test_table select * from source_table;
dbms_output.put_line(to_char(Sysdate,'mi:ss'));
End;
end test;



19:21
-- 50 сек
20:11
-- 48 сек
20:59
-- 82 сек
22:21

В таблице source_table 186708 записей
В таблице test_table в итоге 560124 записей
Времена выполнения сопоставимы (т.е. ожидаемое ускорение - 1,5-2 раза, не более), но никак не в районе десятков минут и более даже на моем домашнем PIII-800/512/NT2000/9i
Похоже, проблема с производительностью твоего сервера :(
PS:

Структура SOURCE_TABLE (имена полей я опустил)
(
NUMBER(12),
VARCHAR2(5),
VARCHAR2(5) not null,
NUMBER(12) not null,
VARCHAR2(10) not null,
DATE not null,
VARCHAR2(5) not null,
VARCHAR2(64) not null,
VARCHAR2(9),
VARCHAR2(80) not null,
VARCHAR2(5) not null,
VARCHAR2(64) not null,
VARCHAR2(9),
VARCHAR2(80) not null,
VARCHAR2(300) not null,
NUMBER(20) not null,
NUMBER(20) not null,
VARCHAR2(2) not null,
NUMBER(1) not null,
NUMBER(3) not null,
VARCHAR2(3) not null,
NUMBER(3) not null,
NUMBER(7) not null,
NUMBER(3) not null,
NUMBER(7) not null,
NUMBER(12),
NUMBER(12),
DATE not null,
DATE not null,
DATE,
DATE not null,
VARCHAR2(1) not null,
VARCHAR2(1) not null,
VARCHAR2(1) not null,
NUMBER(1) not null,
NUMBER(1) not null,
NUMBER(5),
NUMBER(5),
NUMBER(2) not null,
NUMBER(2) not null,
DATE not null,
NUMBER(5),
NUMBER(6) not null,
NUMBER(9)
)
ava
Plamenk | 16.06.2005, 10:11 #
Спасибо за ответы!
А с чем могут быть связаны такие тормаза Сервера? Или может быть неправильная структура БД? Если надо могу выложить структуру таблицы?
ava
igon | 17.06.2005, 01:19 #
Цитата
А с чем могут быть связаны такие тормаза Сервера?

Да с чем угодно!
1. Вываливается в swap из-за недостатка ОЗУ (но у меня тоже диск "шуршит" интенсивно - так что вряд ли из-за этого)
2. Мало дисковой памяти - даже swap негде разместить (очень маловероятно)
3. Процессор занят другими задачами (запросами других пользователей)
и т.д., и т.п

Цитата
Если надо могу выложить структуру таблицы

Если она на порядок сложнее моей или содержит что-то кроме Varchar, Number и Date :)

Что бы я сделал:
1. Установил Oracle на отдельной машине (не обязательно сервере - у меня, как видишь, не суперконфигурация)
2. Перенес таблицу table2 с содержимым, но без индексов, триггеров, constraints и пр., и хранимые.
3. Запустил хранимую
4. Если скорость нормальная - перетащил бы все хозяйство обратно на сервер в ОТДЕЛЬНУЮ схему и попробовал бы там.
...
В общем, вот таким методом "последовательного приближения"


ava
Plamenk | 17.06.2005, 11:39 #
Спасибо буду разбираться!
ava
<Spawn> | 19.06.2005, 19:36 #
Еще вариант - исплользовать опретор forall - он позволяет избежать переключения контекста между SLQ и PL\SQL, что существенно может повысить скорость работы.
ava
Plamenk | 20.06.2005, 14:23 #
А как его использовать?
ava
<Spawn> | 20.06.2005, 18:33 #
Вот пример кода(пишу по памяти):
forall

declare
type t_table is table of number index by binary_integer;
v_table t_table;
v_start number;
begin
v_start := dbms_utility.get_time();
for v_i in 1..100000 loop
v_table(v_i) := v_i;
end loop;
forall v_i in 1..100000
insert into test_table (field) values (v_table(v_i)); -- Понятно что тут можно просто подставить индекс итерации - я лишь для примера привел этот пример
dbms_output.put_line(dbms_utility.get_time() - v_start);
end;


for
declare
v_start number;
begin
v_start := dbms_utility.get_time();
for v_i in 1..100000 loop
insert into test_table (field) values (v_i);
end loop;
dbms_output.put_line(dbms_utility.get_time() - v_start);
end;


Первый пример по сравнению со вторым у меня на работе выполняется примерно в 30 раз быстрее.
added later:
Стоп, я ошибся. Не верно прочитал твой вопрос(с просонья smile ). Мой пример тут вряд ли поможет - смотри, что написал igon.
ava
Paradox | 24.06.2005, 13:02 #
если делается такая процедура постоянно можно еще попробовать для этой таблички увеличить размер экстента
а то может он у тебя 10 кило
поставь 2 метра
должно тоже ускорится
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
advanced
Submit