2015-04-30 4 views
0

Я запускаю процесс ETL и потоковые данные в таблицу MySQL.Улучшение скорости работы SQL 'Update' - перерыв в Insert/Delete?

Теперь он записывается через веб-соединение (довольно быстрое), так что это может быть узким местом.

В любом случае, это базовая функция вставки/обновления. Это список идентификаторов в качестве первичного ключа/индекса ... и затем несколько атрибутов.

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

Выполнение функции «обновление, вставка», основанной на идентификаторе (индексируется), занимает 13 строк в секунду (что кажется довольно ужасным, верно?). Это сравнивает 1000 строк с базой данных 250 тыс. Записей для контекста.

При выполнении «чистой» вставки все приближается, для сравнения, уже ускоряет процесс до 26 строк в секунду.

Дело с чистым подходом «вставки» заключается в том, что я могу иметь 20 параллельных соединений «вставки» сразу ... (20 максимально допустимо для веб-хоста) ... тогда как любая функция «обновления» не может иметь никаких параллели работают.

Таким образом, 26 x 20 = 520 г/с. Довольно больше 13 р/с, особенно если я смогу выстроить что-то, что позволит еще большему количеству данных проходить параллельно.

Мой вопрос ... учитывая огромное преимущество вставки против обновления, есть способ дублировать функциональность «обновления» (я хочу, чтобы только последняя вставка данного идентификатора выдержала) .... сделав массивную вставку, а затем запустив функцию удаления после факта, который удаляет повторяющиеся идентификаторы, которые не являются «новейшими»?

Это что-то простое в реализации или что-то, что появляется часто?

Что еще я могу сделать, чтобы этот процесс обновления был быстрее? Я знаю, что избавиться от «веб-соединения» между инструментом ETL и DB - это начало, но что еще? Похоже, что это будет довольно распространенная проблема.

В конечном счете есть 20 столбцов, максимум, вероятно, varchar (50) ... Должен ли я получать намного больше 13 строк, обработанных/секунд?

+0

Что представляет собой ваш код «update, else insert» в настоящее время? –

ответ

1

Есть много возможных «ответов» на ваши вопросы.

13/второй - много, что можно сделать ...

INSERT ... ON DUPLICATE KEY UPDATE ... («IODKU»), как правило, лучший способ сделать «обновление, иначе вставка» (если я не знаю, что вы под этим подразумевается).

Загруженные вставки намного быстрее, чем вставка одной строки за раз. Оптимальное составляет около 100 строк, что дает 10-кратное ускорение. IODKU может (как правило) также выгружаться; см. псевдослучайную функцию VALUES().

BEGIN; ... много записей ... COMMIT; значительно сокращает расходы на транзакцию.

Использование «промежуточной» таблицы для сбора информации об обновлении может иметь существенную выгоду. My blog discussing that. Это также касается пакетной «нормализации».

Сводные таблицы зданий «на лету» препятствуют высокоскоростной обработке данных. Another blog covers Summary tables.

Нормализация может быть использована для устранения дублирования, что уменьшает площадь дискового пространства. Это может быть важно для уменьшения ввода-вывода для таблицы «Факт» в хранилище данных. (Я имею в виду ваш 20 x VARCHAR(50).)

RAID-разделение - это аппаратная справка.

Батарея с резервным кэшем на RAID-контроллере делает записи кажущимися мгновенными.

SSD ускоряет ввод-вывод.

Если вы предоставите более подробную информацию (SHOW CREATE TABLE, SQL и т. Д.), Я могу быть более конкретным.

1

Сделайте это в СУБД и заверните в транзакцию.

Для объяснения:

  1. Загрузите данные во временную таблицу в MySQL самым быстрым способом. Массовая загрузка, вставка, все, что работает. Посмотрите на «load data infile».

  2. Внешнее соединение временной таблицы с целевой таблицей и ВСТАВЬТЕ те строки, где столбец PK целевой таблицы равен NULL.

  3. Внешнее соединение временной таблицы с целевой таблицей и ОБНОВЛЕНИЕ тех строк, где столбец PK целевой таблицы NOT NULL.

Wrap шаги 2 и 3 в начать/совершить (или [начать транзакцию]/совершить пару для транзакции. Поведение по умолчанию, вероятно, Autocommit, который будет означать, что вы делаете много работы базы данных после того, как каждая вставка/обновление. Используйте транзакции правильно, и работа выполняется только один раз для каждого блока.

Смежные вопросы