Конкретная настройка производительности массовой вставки MySQL

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

У меня есть база данных журналов, содержащая около 10 таблиц. Основная таблица, в которой хранятся фактические записи журнала, имеет около 30 полей, 5 из которых доступны для поиска. Я бы сказал, что база данных в последнее время стала среднего размера, так как мы достигли 200 миллионов записей в этой таблице. В других таблицах хранятся общие данные, самая большая из которых имеет 4 поля, все доступные для поиска, почти с 1 миллионом записей. Все остальные таблицы содержат менее 100 тысяч записей каждая.

Вставки бывают скачкообразными. Я получаю журналы предыдущего дня в (довольно плохо отформатированных) файлах csv каждый день в 2 часа ночи, и у меня есть время до 8 часов, чтобы вставить их (около 20 файлов, по 100 тысяч строк каждый) в базу данных. Затем в течение рабочего дня я получаю очень мало выборов (может быть, около 1000 в день). Затем промойте и повторите.

Запросы SELECT довольно просты, поскольку они в основном состоят из одного или двух объединений с одним или двумя операторами GROUP BY. Люди, выполняющие поиск в этой базе данных, хотят получить немедленные результаты, поэтому у меня есть 5 индексов с несколькими столбцами в основной таблице, которые помогают при точном поиске, который у меня есть, и в настоящее время производительность SELECT довольно хорошая. Пока ни один запрос не занял более 0,1 секунды. Есть несколько отчетов, но их создание занимает около 10 секунд, и это приемлемо.

В настоящее время у меня есть программа на C, которую я написал, чтобы читать данные из файлов CSV, очищать их и вставлять партиями по 1000 строк на каждую. ВСТАВИТЬ запрос. Эти INSERT не совсем тупые, потому что мне нужно получить общие данные, посмотреть, есть ли они уже в других таблицах, вставить их, если нет, и кэшировать, если они есть. Он также дает мне данные о производительности в виде того, сколько записей он вставляет в секунду. Эта программа довольно быстрая, и без отправки данных в базу данных я получаю около 100 тысяч строк в секунду. Конечно, эта программа и база данных находятся на одном физическом компьютере.

Теперь количество данных, которые я получаю каждый день, линейно растет, а производительность операций INSERT логарифмически уменьшается. На вставку вчерашних данных ушло 5 с половиной часов, примерно со скоростью 400 вставок строк в секунду.

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

Таблицы MyISAM: начинается с 1500 строк в секунду, логарифмически уменьшается до примерно 700 строк в секунду к моменту вставки миллионной строки эта программа и база данных находятся на одном физическом компьютере.

Теперь количество данных, которые я получаю каждый день, линейно растет, а производительность INSERT логарифмически уменьшается. На вставку вчерашних данных ушло 5 с половиной часов, около 400 вставок строк в секунду.

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

Таблицы MyISAM: начинается с 1500 строк в секунду, логарифмически уменьшается до 700 строк в секунду к моменту вставки миллионной строки. эта программа и база данных находятся на одном физическом компьютере.

Теперь количество данных, которые я получаю каждый день, линейно растет, а производительность INSERT логарифмически уменьшается. На вставку вчерашних данных ушло 5 с половиной часов, примерно со скоростью 400 вставок строк в секунду.

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

Таблицы MyISAM: начинается с 1500 строк в секунду, логарифмически уменьшается до 700 строк в секунду к моменту вставки миллионной строки. Таблицы InnoDB: такие же, как MyISAM, только примерно на 100 строк в секунду быстрее InnoDB со всеми отключенными индексами в основной таблице: начинается с 2100 строк в секунду, уменьшается до 1000 строк в секунду. InnoDB С индексами, с файловой системой, смонтированной с обратной записью данных (ext3): то же, что и InnoDB, только немного, но почти незаметно быстрее.

innodb_buffer_pool_size установлен на 1000 МБ

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

Системный монитор сообщает мне, что основным потреблением моих ресурсов является дисковый ввод-вывод, который при вставке достигает почти 100%. Из-за этого мне нужен сверхбыстрый способ вставки данных. Мой теоретический предел - это ограничение на шину SATA, но до этого еще далеко. Использование памяти не t кажется таким высоким, около 20% (или MySQL неправильно использует память)

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

Так что я действительно открыт для идей. Кто-нибудь знает что-нибудь, что могло бы мне помочь?

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

9
задан 26 February 2011 в 15:39
поделиться