@Richard_Ferlow
Веб-программист

MYSQL Insert — импорт json файла с большим количеством данных — как?

Продолжая тему - импортирую в базу MySQL данные получаемые по API от партнера.
Данные он отдает в формате JSON. Данные - информация по отелям в конкретном городе - полные- название, адрес, ссылки на фотографии и т.д.

И вот допустим беру Москву - в json для импорта 1301 отелей, 32 тысячи записей о фотографиях.

И вот не могу эту информацию в базу занести - не хватает мощности что ли, или настройки какие не те где-то.

Импорт делаю на VPS
Xeon 2600 series, 1 ядро
1024 Мб RAM
32 Гб SSD

Импорт следующий
api удаленное, получаю файл через file_get_contents, далее json_decode
и дальше циклом for прохожусь по массиву полученному.

В каждой итерации - insert на добавление отеля
потом еще несколько insert для опций отеля в следующие отдельные таблицы и самый большой -
insert с множеством строк для фотографий.

Так вот - сервер похоже не вывозит выпадая с 500 ошибкой. график нагрузки до 97% растет - подозреваю что из-за этого как раз и поэтому обрубается все.

Сервер настраивал сам - вернее развернул VESTA, для php лимит времени до 120 увеличил и конфиг mysql крутил.

В общем как быть? Это только Москва, а городов больше 30тыс. ясно что во многих городах отелей много меньше, но все равно крупных городов хватает.
  • Вопрос задан
  • 7381 просмотр
Пригласить эксперта
Ответы на вопрос 6
Assargin
@Assargin
Перед ответом смотрю наличие ✔ в ваших вопросах
Из личного опыта:
- "сервер похоже не вывозит выпадая с 500 ошибкой" - а лог ошибок на что? Там все написано, почему падает.
- самое страшное - делать запросы на изменение данных вне явно открытой транзакции в транзакционную таблицу (InnoDB). set autocommit=0, стартуете транзакцию и можно циклом вставлять данные. Неявная транзакция на каждый запрос замедляет работу раз в 100-200.
- вариант @zelenin'а c пакетным запросом - вообще не пробовал, но может быть хорошей альтернативой явным транзакциям.
- нет никакой нужды выполнять такое через веб, и иметь нюансы, с ним связанные - таймлимиты php и самого веб-сервера. Выполняйте импорт, запуская скрипт из командной строки. Я так демонов делал, работали по принципу "запустил и забыл", но это уже совсем другая история.
Вообще ~1300 записей о отелях и 32000 фотки (чисто url'ы с описаниями, наверно?) - не так много данных, скорее всего узкое место у вас - именно передача данных из PHP в MYSQL.
Ответ написан
@portfelio
Если абстрагироваться от возможных недочетов в области правильной настройки софта, то правильнее было бы json превращать в sql-файл и потом загружать его в mysql через dev.mysql.com/doc/refman/5.1/en/load-data.html
Ответ написан
hOtRush
@hOtRush
500 ошибка - это ошибка в коде может быть, какой текст ошибки?

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

плюс есть либы для "построчного" чтения json, может тоже поможет.

и какая версия пхп, может течет что-нибудь?
Ответ написан
самая банальная ошибка - инсерты в цикле. В цикле нужно собирать 1 большой инсерт вида:
insert table (id,name,value) values (1,x,x),(2,x,x) и тд. А после цикла уже его выполнять. Если данных очень много, можно не одним инсертом вставлять данные, а несколькими (по 1-10т записей за раз).
Ответ написан
begemot_sun
@begemot_sun
Программист в душе.
Память для php увеличивали ?
Ответ написан
@tushev
При массовой вставке или апдейте записей в MySQL очень сильное ускорение можно получить если завернуть пачку INSERT-ов или UPDATE-ов в транзакцию. Можно вообще вообще весь импорт сделать за одну транзакцию, можно разрезать на несколько более мелких транзакций.

Ну а вообще, разберитесь в каком месте у вас все падает или жрет слишком много времени и ресурсов. Разбейте задачу на несколько кусков, и выполните каждую по отдельности.
- чтение данных из удаленного источника
- json парсинг
- формирование SQL команд
- выполнение SQL команд

Тогда поймете, в каком именно месте у вас проблема.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы