INSERT 6000 Rows - лучшая практика - PullRequest
3 голосов
/ 02 апреля 2009

У меня есть PHP-скрипт, который вызывает метод API, который может легко вернуть результаты 6k +.

Я использую PEAR DB_DataObject для записи каждой строки в цикле foreach в БД.

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

Кажется, что цикл вызова API в порядке, партии по 20 раз в 5 минут работают нормально. Мое единственное беспокойство - 1000 вставок mysql для каждого пользователя (с длинной паузой между каждым пользователем для новых вызовов API)

Есть ли хороший способ сделать это? Или я делаю это хорошо?!

Ответы [ 7 ]

4 голосов
/ 02 апреля 2009

Ну, самый быстрый способ сделать это - сделать один оператор вставки с большим количеством значений, например:

INSERT INTO mytable (col1, col2) VALUES ( (?,?), (?,?), (?,?), ...)

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

2 голосов
/ 02 апреля 2009

Как сказал Калиум, проверьте, где находится узкое место. Если это действительно база данных, вы можете попробовать функцию массового импорта, предлагаемую некоторыми СУБД.

Например, в DB2 это называется LOAD. Он работает без SQL, но читает напрямую из именованного канала. Это специально разработано, чтобы быть быстрым, когда вам нужно принести большое количество новых строк в базу данных. Он может быть настроен на пропуск проверок и создание индекса, что делает его еще быстрее.

1 голос
/ 02 апреля 2009

Хорошо, ваш метод производит больше нагрузки, чем вы можете выдержать? Если он работает, то я не вижу смысла менять его на месте.

0 голосов
/ 03 апреля 2009

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

Что касается вашего метода, убедитесь, что вы делаете каждого пользователя (или пакет) в отдельной транзакции. Если mysql, убедитесь, что вы используете innodb, чтобы избежать ненужной блокировки. Если вы уже используете базу данных innodb / postgres / other, которая поддерживает транзакции, вы можете значительно увеличить производительность.

Подумайте об использовании COPY (по крайней мере на postgres - не уверены насчет mysql).

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

Не забывайте регулярно оптимизировать / вакуумировать.

0 голосов
/ 02 апреля 2009

MySQL LOAD DATA INFILE функция, вероятно, самый быстрый способ сделать то, что вы хотите.

Вы можете взглянуть на главу Скорость операторов INSERT в документации MySQL.

В нем рассказывается о многих способах улучшения ВСТАВКИ в MySQL.

0 голосов
/ 02 апреля 2009

У меня есть несколько идей, но вам придется проверить их с помощью тестирования.

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

Проверьте варианты оптимизации здесь: http://dev.mysql.com/doc/refman/5.0/en/insert-speed.html

Рассмотрим mysqli напрямую или Pear :: MDB2 или PDO. Я понимаю, что Pear :: DB работает довольно медленно, хотя я сам не использую PEAR, поэтому не могу проверить.

0 голосов
/ 02 апреля 2009

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

Как сказали Эрик Р и weinzierl.name, использование многорядной вставки или LOAD обеспечит наилучшую производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...