Вставка SQL с большим набором данных

Как мы обрабатываем размер фиксации при выполнении запроса типа «вставить в таблицу»? Т.е. все ли записи из anotherTable вставлены в одну транзакцию ИЛИ есть ли способ установить размер фиксации?

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

Для новичков: постарайтесь не добавлять в вопрос лишние элементы. Используйте раздел комментариев (экономно) для того же. :) Бит за битом делает байт.

Suvarna Pattayil 30.05.2014 23:25
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
1
4 015
12

Ответы 12

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

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

но с большими пластинами это обычно неоптимально.

Bob Probst 31.12.2008 05:50

Не уверен, почему этот ответ отвергается, поскольку он правильный.

Nick Pierpoint 08.01.2009 15:46

Мне ни один ник никогда этого не понять.

JoshBerke 08.01.2009 23:19

Если вам нужно ограничить набор данных, включите это ограничение в запрос.

Например, на языке Microsoft SQL Server вы можете использовать «TOPN», чтобы убедиться, что запрос возвращает только ограниченное количество строк.

INSERT INTO thisTable
  SELECT TOP 100 * FROM anotherTable;

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

Я не хочу использовать цикл where, потому что это может увеличить производительность. Не так ли?

~ Шри

Вы должны пометить свой вопрос словом «oracle», поскольку сегмент отката IIRC является функцией Oracle.

Bill Karwin 31.12.2008 05:51

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

RSlaughter 31.12.2008 06:02

Можете ли вы добавить это как модификацию к исходному вопросу?

David Aldridge 02.01.2009 18:08

@sri Это не ответ, это должен быть комментарий или редактирование исходного вопроса

schmidlop 21.03.2017 18:57

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

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

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

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

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

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

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

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

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

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

Если вас устраивает вставка одних строк и сбоев других по какой-либо причине, добавьте поддержку обработки сбоев, используя синтаксис ВСТАВИТЬ ВЗАПИСАТЬ ОШИБКИ В.

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

К сожалению, индекс NOLOGGING применяется только тогда, когда создание индекса.

Jon Heller 01.06.2014 11:59

@jonearles, из документации, которую вы связали: «Этот параметр также определяет, будут ли регистрироваться в журнале последующие операции INSERT ... прямого пути к индексу». Вы можете использовать подсказку добавления, чтобы получить прямую вставку пути.

RussellH 17.07.2014 04:08

Хорошая мысль, надо было внимательнее прочитать свою ссылку! Но я все же считаю правильным сказать, что NOLOGGING применяется только при создании или перестроении индекса. В эта ветка AskTom Том несколько раз повторяет одно и то же. Некоторые другие онлайн-источники и мои простые тесты также согласны с тем, что NOLOGGING не уменьшает повторное выполнение индекса во время вставки прямого пути. Я отправил комментарий к документации, хотя не уверен, что это когда-нибудь принесет пользу.

Jon Heller 17.07.2014 11:05

Я говорил о сокращении отмены. Из той же ветки AskTom: «Отмена будет минимизирована для индекса, но должна быть сгенерирована ...» asktom.oracle.com/pls/asktom/… Из этой цитаты не ясно, как влияет NOLOGGING на индекс.

RussellH 17.08.2014 02:40

К сожалению, это не помогает и с UNDO. Смотрите мой ответ / комментарий ниже. Я не уверен, что Зачем это не поможет, это была бы очень полезная функция, если бы она работала.

Jon Heller 17.08.2014 19:58
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 переменными. Это лучше, чем делать по одной записи за раз.

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

-1 потому что это ужасно медленный подход. Для таблицы из 100 000 записей вы обращаетесь к «TableSelected» 1000 раз, и каждый доступ, вероятно, представляет собой полное сканирование таблицы ...

Rob van Wijk 06.06.2009 14:09

Вы предполагаете, что это всегда сканирование таблицы. хорошо, поместите данные во временную таблицу. Где твой лучший способ? Не смотри здесь.

Lurker Indeed 08.06.2009 20:46

Это расширенный комментарий, демонстрирующий, что установка индексов на 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

Другие вопросы по теме