Как вставить очень много INSERT за один раз из строк в файле (php)?
Суть такова: скрипт сбрасывает в текстовый файл либо строки, либо готовые выражения, потом скрипт-вставлятор-в-бд парсит файл и либо берет команды оттуда либо на основе текстовых строк генерирует insert. Вопрос, собственно, вот в чем - как правильно оформить множественные insert'ы в базу, чтобы получилось максимально быстро? Файлы могут быть до ~5 мб, поэтому нагрузка довольно неплохая будет. Какие опции при insert нужно включить и как правильно сформировать запрос? В одной вставке, например можно сразу несколько записей сделать типа INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);, на каково максимальное/оптимальное количество? Спасибо.
astrotrain: Нет, не нужны. Это самый быстрый из всех возможных способов вставки большого объема данных в таблицу. Более того, он очень гибкий - их можно преобразовывать еще при этом, или писать не все столбцы из источника, например. Значение max_allowed_packet по умолчанию - 16MB, это очень много на самом деле. Количиство записей при этом не ограничено.
Aleksey: Спасибо, звучит неплохо. А что если получится ситуация, когда исходный файл будет больше чем нужно и скрпт выдаст ошибку, как тогда реагировать, файл на куски делить?
Если сервер ваш, или его обслуживает ваш DBA, можно увеличить max_allowed_packet (максимальный размер - 1GB). Если же нет, то да, надо будет считывать по частям. Либо вы заранее складываете не в один файл, в в несколько, скажем, по 1000 строк. Однако, я повторюсь: CSV в 16 MB - это реально очень много.
Aleksey: Но все же "Also, to use LOAD DATA INFILE on server files, you must have the FILE privilege." Но в любом случае, оставлю это запасным вариантом.
Сформировать CSV и скормить через LOAD DATA INFILE напрямую в базу.
Если с load data не получается, то в одной транзакции скармливаете множественные insert'ы (насколько множественные - см max_allowed_packet)
5 мб данных не так уж и много.
Это получается, что я могу составить множественный запрос размером в max_allowed_packet? Интересно, но мне нужно программно же как-то проверить сколько записей можно в такой insert запихнуть, перед тем как формировать такой запрос. Как это сделать?