Советы по переносу огромного объема данных из одной таблицы в другую?

#sql #oracle

Вопрос:

Мы должны разделить один стол на два.

Наш текущий рабочий сценарий выглядит следующим образом:

  1. отключите ограничения для новых таблиц
  2. INSERT INTO newTable1 SELECT... FROM oldTable
  3. INSERT INTO newTable2 SELECT... FROM oldTable WHERE fieldX IS NOT NULL
  4. повторно включить ограничения

В то же время мы также исследуем использование параллелизма (до сих пор в наших тестах по какой-то причине не было никаких улучшений…).

Кроме того, что еще мы могли бы использовать для безопасной и быстрой миграции в PROD?

Комментарии:

1. Почему вы перемещаете все данные из одной таблицы в другую (в newTable1 вас нет фильтров)? Вы можете rename использовать его или использовать синоним, если хотите, чтобы он был в другой схеме.

2. @astentx Я делаю фильтр в ВЫБОРЕ. Цель состоит в том, чтобы иметь 2 таблицы. Мощность некоторых полей из oldTable изменилась с 0..1 до 0..n (то есть теперь они представлены в виде элемента в списке и имеют в качестве родительской oldTable).

3. INSERT INTO newTable1 SELECT... FROM oldTable здесь нет никакой фильтрации. Вам действительно нужна копия данных?

4. @astentx, чувак, я поставил 3 точки, просто чтобы упростить это… ВСТАВИТЬ В НОВУЮ ТАБЛИЦУ 1 ВЫБЕРИТЕ поле 1, поле 2, поле 3 ИЗ старой ТАБЛИЦЫ

5. Позвольте мне угадать: вы не перемещаете все поля из oldTable в newTable1, например, только a, b и c? Вы перемещаете другие поля d, e и f, где поле x не равно нулю, из таблицы oldTable в дочернюю таблицу newTable2. Предположим, что это так, прежде чем мы спустимся в кроличью нору и проигнорируем ваш первоначальный вопрос: параллелизм может не повысить производительность, в зависимости от того, о каком объеме данных вы говорите и как ваша БД настроена для его поддержки. Зависит от того, где находится ваше узкое место: процессор, дисковый ввод-вывод, коммутаторы журналов, емкость буферного кэша и т.д. Какие события ожидания вы наблюдаете?

Ответ №1:

Двумя основными инструментами для повышения производительности вставки больших таблиц являются запись по прямому пути и параллелизм, и они хорошо работают вместе.

Записи по прямому пути помещают данные непосредственно в файлы данных и обходят создание дополнительных данных ПОВТОРА и отмены. Эта функция значительно сокращает ввод-вывод, но это означает, что ваша новая таблица не может быть восстановлена до следующего полного резервного копирования.

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

Прежде чем вы потратите целый день на то, чтобы прочитать и понять главу «Использование параллельного выполнения» Руководства по VLDB и разделению, есть простой способ попробовать и протестировать эти две функции. Если вам повезет, все, что вам нужно,-это приведенный ниже код, и вам, возможно, даже не придется беспокоиться об отключении и повторном включении противопоказаний:

 alter session enable parallel dml;
insert /*  parallel(8) append */ into newtable select * from oldtable;
commit;
 

Если это не сработает, посмотрите на план объяснения, и вы должны увидеть что-то вроде этого:

 alter session enable parallel dml;
explain plan for insert /*  parallel(8) append */ into newtable select * from oldtable;
select * from table(dbms_xplan.display);


Plan hash value: 1569336347
 
----------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name     | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                   |          |     1 |    13 |     2   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR                    |          |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)              | :TQ10000 |     1 |    13 |     2   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    LOAD AS SELECT (HYBRID TSM/HWMB)| NEWTABLE |       |       |            |          |  Q1,00 | PCWP |            |
|   4 |     OPTIMIZER STATISTICS GATHERING |          |     1 |    13 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
|   5 |      PX BLOCK ITERATOR             |          |     1 |    13 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|   6 |       TABLE ACCESS FULL            | OLDTABLE |     1 |    13 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
----------------------------------------------------------------------------------------------------------------------------
 
Note
-----
   - dynamic statistics used: dynamic sampling (level=2)
   - Degree of Parallelism is 8 because of hint
 

Обратите внимание на четыре ключевых пункта в плане объяснения: «ЗАГРУЗКА ПО ВЫБОРУ» вместо «ЗАГРУЗКА ПО ОБЫЧНОМУ» означает, что вы используете запись по прямому пути, операция «PX» над «ПОЛНЫЙ ДОСТУП к ТАБЛИЦЕ» подразумевает, что вы используете параллельное чтение, операция «PX» над «ЗАГРУЗКА ПО ВЫБОРУ» подразумевает, что вы используете параллельную запись, а «Степень параллелизма» указывает, сколько параллельных потоков запрашивается.

Если какой-либо из этих элементов отсутствует, изучите раздел «Примечание», и он часто будет объяснять, почему вы не получили то, что просили. Если у вас все еще возникают проблемы, опубликуйте полный план объяснения в виде текста, и мы поможем устранить проблему.