Вставка SQL с большим набором данных - PullRequest
3 голосов
/ 31 декабря 2008

Когда мы выполняем запрос типа "вставить в таблицу", как мы обрабатываем размер коммита? То есть все записи из другого таблицы вставлены в одну транзакцию ИЛИ есть ли способ установить размер коммита?

Большое спасибо ~ Шри PS: Я здесь первый таймер, и этот сайт выглядит очень хорошо!

Ответы [ 12 ]

3 голосов
/ 02 января 2009

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

3 голосов
/ 31 декабря 2008

В хороших базах данных это атомарное утверждение, так что нет, нет способа ограничить количество вставляемых записей - это хорошо!

2 голосов
/ 31 декабря 2008

Я написал код на разных языках, в основном на Java, для массовых вставок, как вы описали. Каждый раз, когда я делал это, в основном путем анализа какого-либо входного файла или чего-то в этом роде, я в основном просто подготавливал подмножество данных для вставки из общего объема (обычно 4000 или около того) и передавал эти данные нашему слою DAO , Так было сделано программно. Мы никогда не замечали какого-либо реального падения производительности для этого, и мы имели дело с несколькими миллионами записей. Если у вас есть большие наборы данных для вставки, операция «займет некоторое время» независимо от того, как вы это делаете.

1 голос
/ 02 января 2009

Дэвид Олдридж прав, размер сегмента отката в зависимости от максимальной транзакции, когда вы хотите, чтобы ВСТАВКА была успешной или неудачной в целом.

Некоторые альтернативы:

Если вам не нужна возможность откатить его (для этого и существует сегмент), вы можете изменить ALTER TABLE и добавить предложение NOLOGGING . Но это не мудрый шаг, если вы не загружаете таблицу отчетов, в которую вы удаляете все старые строки и загружаете новые, или в некоторых других особых случаях.

Если вы согласны, что некоторые строки вставляются, а другие по какой-то причине не работают, добавьте поддержку обработки сбоев, используя синтаксис INSERT INTO LOG ERRORS INTO .

1 голос
/ 31 декабря 2008

Вы не можете обработать размер коммита, если вы явно не закодируете его. Например, вы можете использовать цикл where и написать код для ограничения количества выбранных вами данных.

0 голосов
/ 17 августа 2014

Это расширенный комментарий, демонстрирующий, что установка индексов в NOLOGGING не поможет уменьшить UNDO или REDO для INSERT.

В руководстве подразумевается, что индексы NOLOGGING могут помочь улучшить DML за счет уменьшения UNDO и REDO. И поскольку NOLOGGING помогает с таблицей DML, кажется логичным, что это также поможет с изменениями INDEX. Но этот тестовый пример демонстрирует, что изменение индексов на NOLOGGING не влияет на операторы INSERT.

drop table table_no_index;
drop table table_w_log_index;
drop table table_w_nolog_index;

--#0: Before
select name, value from v$mystat natural join v$statname where display_name in ('undo change vector size', 'redo size') order by 1;

--#1: NOLOGGING table with no index.  This is the best case scenario.
create table table_no_index(a number) nologging;
insert /*+ append */ into table_no_index select level from dual connect by level <= 100000;
commit;
select name, value from v$mystat natural join v$statname where display_name in ('undo change vector size', 'redo size') order by 1;

--#2: NOLOGGING table with LOGGING index.  This should generate REDO and UNDO.
create table table_w_log_index(a number) nologging;
create index table_w_log_index_idx on table_w_log_index(a);
insert /*+ append */ into table_w_log_index select level from dual connect by level <= 100000;
commit;
select name, value from v$mystat natural join v$statname where display_name in ('undo change vector size', 'redo size') order by 1;

--#3: NOLOGGING table with NOLOGGING index.  Does this generate as much REDO and UNDO as previous step?
create table table_w_nolog_index(a number) nologging;
create index table_w_nolog_index_idx on table_w_nolog_index(a) nologging;
insert /*+ append */ into table_w_nolog_index select level from dual connect by level <= 100000;
commit;
select name, value from v$mystat natural join v$statname where display_name in ('undo change vector size', 'redo size') order by 1;

Вот результаты статистических запросов. Числа являются накопительными для сессии. Тестовые случаи # 2 и # 3 имеют одинаковое увеличение UNDO и REDO.

--#0: BEFORE: Very little redo or undo since session just started.
redo size      35,436
undo change vector size    10,120

--#1: NOLOGGING table, no index: Very little redo or undo.
redo size      88,460
undo change vector size    21,772

--#2: NOLOGGING table, LOGGING index: Large amount of redo and undo.
redo size   6,895,100
undo change vector size 3,180,920

--#3: NOLOGGING table, NOLOGGING index: Large amount of redo and undo.
redo size   13,736,036
undo change vector size 6,354,032
0 голосов
/ 12 января 2009
INSERT INTO TableInserted
SELECT *
FROM (
   SELECT  *,
          ROW_NUMBER() OVER (ORDER BY ID) AS RowNumber
   FROM TableSelected
) X
WHERE RowNumber BETWEEN 101 AND 200

Вы можете довольно легко обернуть вышеописанное в цикл while, заменив 101 и 200 переменными. Это лучше, чем делать 1 запись за раз.

Я не знаю, какие версии Oracle поддерживают оконные функции.

0 голосов
/ 12 января 2009

Вы можете просто захотеть сделать индексы NOLOGGING. Таким образом, данные таблицы могут быть восстановлены, но индексы необходимо будет восстановить, если таблица будет восстановлена. Ведение индекса может привести к значительным ошибкам.

0 голосов
/ 02 января 2009

"Причина, по которой я хочу сделать это, состоит в том, чтобы избежать сегмента отката, выходящего из пространства. Кроме того, я хочу, чтобы результаты заполнялись в целевой таблице через регулярные промежутки времени."

Первый - это просто правильное определение размера табличного пространства отмены. Поскольку отмена - это удаление существующей строки, она не требует много места. И наоборот, удаление, как правило, требует больше места, поскольку для его повторной вставки требуется отменить копию всей удаленной строки.

Для второго взгляните на v $ session_longops и / или row_processed в v $ sql

0 голосов
/ 31 декабря 2008

Вы правы, вы можете запускать большие вставки партиями. Прикрепленная ссылка показывает способ сделать это в SQL Server, если вы используете другой бэкэнд, вы должны сделать что-то похожее, но точный синтаксис может отличаться. Это тот случай, когда цикл приемлем.

http://www.tek -tips.com / faqs.cfm? FID = 3141

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