Oracle 11g: повышение производительности вставок

8

У меня есть таблица 500 миллионов строк (и растет)

Я сделал следующее, чтобы улучшить производительность вставок:

На стороне базы данных:

  • отбросил все индексы и ограничения
  • отключено ведение журнала

На стороне приложения:

  • переключился с управляемых объектов JPA на собственные запросы вставки, добавил к запросу подсказку APPEND Oracle
  • пытался фиксировать в пакетах на 1k / 2k / 3k строк
  • попытался записать параллельно (несколько потоков, число потоков = число ядер на сервере) в одну таблицу

Это дало мне около 300 строк в секунду

Дополнительно попробовал:

  • параллельная запись в несколько таблиц (чтобы сгруппировать, а затем вернуть результаты с помощью UNION)

Это дало мне около 1 тыс. Строк в секунду, но на пустых таблицах. Но когда я заполнил таблицы фиктивными данными (по 200 миллионов каждая), скорость вставок упала до 250–300 в секунду.

Кто-нибудь может подсказать, что еще можно сделать для ускорения вставок? В основном я хочу понять, что является (что может быть) узким местом в первую очередь.

UPD: таблица разбита по дате вставки, таблица имеет около 60 столбцов - большинство столбцов VARCHAR2 (2000 BYTE)

дрейфовать
источник
Вы знаете, что при отключенном ведении журнала сбой носителя между загрузкой и завершением первого последующего резервного копирования оставит всю таблицу или ее части в случае прямой вставки пути невосстановимым, верно?
Дэвид Олдридж
1
(1) Только один сеанс может ПРИЛОЖИТЬ в любой момент времени на столе. (2) /*+APPEND*/подсказка игнорируется при вставке в одну строку (если у вас нет необходимости INSERT INTO ... SELECTдобавлять). (3) Вам следует установить пример загрузчика SQL * с помощью, direct=trueчтобы установить базовый уровень, как это предлагается @parsifal.
Винсент Малграт
Вы работаете на реальном оборудовании или виртуальной машине? Если виртуальная машина, файлы на диске редкие (то есть: не полностью предварительно выделены)? Также, пожалуйста, отредактируйте ваш вопрос с выводом из отчета statspack или awr (верхний раздел ожидания).
Philᵀᴹ
Какую проблему / потребность решает / удовлетворяет разделение по дате вставки?
Брайан
Каков источник ваших данных для этой таблицы? Это пакетная загрузка из файла ASCII или это пользовательский или что-то еще. Пожалуйста, будьте конкретны.
RMAN Express

Ответы:

5

Только что увидел обновление, 60-столбцовую таблицу с в основном полями VARCHAR (2k) - это (потенциально) таблица монстров.

Обо всем по порядку ...

Вы должны понять свое узкое место в первую очередь. Со стороны приложения, вернитесь к своему однопоточному пакетному решению (1/2 / 3k за раз) и начните запускать его, войдите в систему на компьютере с БД и запустите «top» - посмотрите, сколько время, которое занимает процесс БД И сколько (если есть) ва% времени, которое машина показывает.

Если top показывает ЛЮБОЙ w% времени, это означает, что ваша БД привязана к вводу / выводу, и вам, вероятно, нужно рассмотреть несколько машин БД (сегментов) или рассмотреть возможность размещения SSD на хост-машине.

Это оно; Ваше исследование останавливается здесь. Неважно, сколько процессора занимает БД или насколько насыщен ваш клиент приложения; если вы сталкиваетесь с проблемами задержки ввода / вывода на хосте DB, это так же быстро, как и когда-либо.

СОВЕТ Если об аппаратных изменениях не может быть и речи, в зависимости от используемой файловой системы (Linux) вы можете попробовать отключить ведение журнала или запись метаданных для БД, чтобы немного повысить производительность на уровне файловой системы. Вы можете сделать что-то подобное в NTFS, но это даст вам небольшой импульс. Это не будет 2х.

Теперь вторые вещи вторые ...

Допустим, у вас было почти нет времени, но ваш процессор полностью привязан процессом БД. Ваша единственная возможность сейчас состоит в том, чтобы ввести больше машин (сегментов) БД и разделить работу.

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

Наконец, третье ... третье ...

Допустим, БД ничего не делает. Затем перейдите к клиентскому компьютеру, на котором выполняется пакетная вставка, и проверьте загрузку процессора - он не привязан? Если это так, запустите еще несколько машин, делающих те же пакетные вставки, и посмотрите, сможете ли вы получить линейную рампу.

Если процессор не привязан, запустите еще несколько потоков на той же машине, пока он не будет привязан, и посмотрите, как масштабируется БД.

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

добавление

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

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

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

Надеюсь, это поможет! Держать нас в курсе.

Рияд Калла
источник
2
Почему вы не упомянули awr или statspack?
Philᵀᴹ
С подсказкой добавления все, кроме одного из этих потоков, будут простаивать из-за исключительной блокировки. Я не думаю, что этот код находится на этапе эффективности, где требуется настройка на уровне системы - это сама методология, которая имеет недостатки.
Дэвид Олдридж
Если подумать дальше, я считаю, что у вашего подхода есть фундаментальный недостаток. Если Виктор использовал однопоточный метод пакетной вставки и имел время ожидания ввода-вывода, это могло быть вызвано неэффективным методом вставки и чрезмерной фиксацией (ожидание синхронизации файла журнала). Самый важный шаг должен состоять в том, чтобы понять механизмы Oracle и сначала выбрать наиболее подходящий из них, конечно же?
Дэвид Олдридж
@DavidAldridge Viktors пояснил, что он отключил ведение журнала (и индексы), учитывая, что я предположил, что БД ничего не делал, кроме потоковой передачи вставленных данных прямо в файл таблицы, поэтому я заставил его перейти прямо к просмотру Ожидание ввода / вывода Может быть, есть больше Oracle, который должен / может быть отключен - это хорошая точка исследования, я не знаю достаточно глубины Oracle, чтобы помочь там, к сожалению.
Рияд Калла
4

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

insert /*+ append */ into my_table partition (partition_name_1) ...

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

Не фиксируйте в середине вставки, только в конце.

Дэвид Олдридж
источник
Нужно ли явно указывать имя раздела в запросе? У меня есть столбец, своего рода тип события. Я собираюсь попытаться разделить по группам событий и сделать так, чтобы каждый поток вставлял партии строк только определенного типа
по течению
Чтобы избежать эксклюзивной блокировки на уровне таблицы, да, вы делаете.
Дэвид Олдридж
Подсказка APPEND должна игнорироваться Oracle для вставок в одну строку. Описание процесса OP, по-видимому, подразумевает пакетные однорядные вставки. Я не уверен, как к ним относятся, хотя. Я бы предположил, что нет ПРИЛОЖЕНИЯ, но это требует некоторого тестирования.
Винсент Малграт
Хммм, не учел этого - еще хуже, если так.
Дэвид Олдридж
Стоит ли пробовать многорядные вставки с подсказкой APPEND? Тогда сколько записей на многострочную вставку я должен отправить?
по течению