У меня есть таблица 500 миллионов строк (и растет)
Я сделал следующее, чтобы улучшить производительность вставок:
На стороне базы данных:
- отбросил все индексы и ограничения
- отключено ведение журнала
На стороне приложения:
- переключился с управляемых объектов JPA на собственные запросы вставки, добавил к запросу подсказку APPEND Oracle
- пытался фиксировать в пакетах на 1k / 2k / 3k строк
- попытался записать параллельно (несколько потоков, число потоков = число ядер на сервере) в одну таблицу
Это дало мне около 300 строк в секунду
Дополнительно попробовал:
- параллельная запись в несколько таблиц (чтобы сгруппировать, а затем вернуть результаты с помощью UNION)
Это дало мне около 1 тыс. Строк в секунду, но на пустых таблицах. Но когда я заполнил таблицы фиктивными данными (по 200 миллионов каждая), скорость вставок упала до 250–300 в секунду.
Кто-нибудь может подсказать, что еще можно сделать для ускорения вставок? В основном я хочу понять, что является (что может быть) узким местом в первую очередь.
UPD: таблица разбита по дате вставки, таблица имеет около 60 столбцов - большинство столбцов VARCHAR2 (2000 BYTE)
/*+APPEND*/
подсказка игнорируется при вставке в одну строку (если у вас нет необходимостиINSERT INTO ... SELECT
добавлять). (3) Вам следует установить пример загрузчика SQL * с помощью,direct=true
чтобы установить базовый уровень, как это предлагается @parsifal.Ответы:
Только что увидел обновление, 60-столбцовую таблицу с в основном полями VARCHAR (2k) - это (потенциально) таблица монстров.
Обо всем по порядку ...
Вы должны понять свое узкое место в первую очередь. Со стороны приложения, вернитесь к своему однопоточному пакетному решению (1/2 / 3k за раз) и начните запускать его, войдите в систему на компьютере с БД и запустите «top» - посмотрите, сколько время, которое занимает процесс БД И сколько (если есть) ва% времени, которое машина показывает.
Если top показывает ЛЮБОЙ w% времени, это означает, что ваша БД привязана к вводу / выводу, и вам, вероятно, нужно рассмотреть несколько машин БД (сегментов) или рассмотреть возможность размещения SSD на хост-машине.
Это оно; Ваше исследование останавливается здесь. Неважно, сколько процессора занимает БД или насколько насыщен ваш клиент приложения; если вы сталкиваетесь с проблемами задержки ввода / вывода на хосте DB, это так же быстро, как и когда-либо.
СОВЕТ Если об аппаратных изменениях не может быть и речи, в зависимости от используемой файловой системы (Linux) вы можете попробовать отключить ведение журнала или запись метаданных для БД, чтобы немного повысить производительность на уровне файловой системы. Вы можете сделать что-то подобное в NTFS, но это даст вам небольшой импульс. Это не будет 2х.
Теперь вторые вещи вторые ...
Допустим, у вас было почти нет времени, но ваш процессор полностью привязан процессом БД. Ваша единственная возможность сейчас состоит в том, чтобы ввести больше машин (сегментов) БД и разделить работу.
Опять же, вы закончили свои исследования, если это так. Вы ничего не можете сделать, чтобы ускорить процессор.
Наконец, третье ... третье ...
Допустим, БД ничего не делает. Затем перейдите к клиентскому компьютеру, на котором выполняется пакетная вставка, и проверьте загрузку процессора - он не привязан? Если это так, запустите еще несколько машин, делающих те же пакетные вставки, и посмотрите, сможете ли вы получить линейную рампу.
Если процессор не привязан, запустите еще несколько потоков на той же машине, пока он не будет привязан, и посмотрите, как масштабируется БД.
Я думаю, что вы, возможно, уже пробовали это, поэтому я предполагаю, что либо ваш клиентский хост уже был привязан (и больше потоков не будет иметь значения), либо БД уже достигла своего предела и не может масштабироваться дальше.
добавление
Выполнение необработанных вставок в неиндексированную таблицу, в которой нет мусора, по сути является операцией APPEND, которая должна выполняться так же быстро, как диск может обрабатывать записи.
Создание большего количества таблиц на одном и том же хосте не поможет, если что-то увеличит ваши запросы к диску (чтобы добраться до других таблиц на диске, к которому нужно добавить) и замедлит работу.
Крайне важно сначала выяснить это узкое место, а затем мы можем его оптимизировать.
Надеюсь, это поможет! Держать нас в курсе.
источник
Вызов прямой вставки пути с подсказкой добавления вызывает исключительную блокировку всей таблицы, поэтому выполнение нескольких потоков не поможет. Вы должны были бы явно обратиться к другому разделу с каждой вставкой ...
... чтобы получить эксклюзивные блокировки на уровне раздела. Скорее всего, вы не сможете сделать это с таблицей, разделенной на дату вставки, но вы можете использовать составное разбиение (не разделение на части), чтобы получить несколько разделов на уникальный диапазон дат вставки.
Не фиксируйте в середине вставки, только в конце.
источник