Есть Способ, которым я могу обновить 100k записей в запросе, и база данных mysql будет работать плавно?
Предположим, что есть пользователи таблицы, содержащие сотни тысяч записей, и мне нужно обновить около пятидесяти тысяч записей, а для обновления у меня есть идентификаторы этих записей, что означает около пятидесяти тысяч записей, хранящихся в файле csv,
1 – Будет ли запрос удовлетворительным, поскольку размер запроса будет слишком большим? или если есть какой-то способ поставить в маленькие чанки, дайте мне знать?
2- Учитывая структуру laravel, если есть возможность прочитать часть файла, а не весь файл, чтобы избежать утечки памяти. Поскольку я не хочу читать все файлы одновременно, пожалуйста, предложите.
Любое предложение приветствуется!
Если вы думаете создать такой запрос, как UPDATE users SET column = 'value' WHERE id = 1 OR id = 2 OR id = 3 ... OR id = 50000
или WHERE id IN (1, 2, 3, ..., 50000)
то это, вероятно, будет слишком большим. Если вы можете сделать некоторую логику, чтобы суммировать это, это значительно сократило бы запрос и ускорило бы дело до конца MySQL. Возможно, вы могли бы сделать это WHERE id >= 1 AND id <= 50000
.
Если это не вариант, вы можете сделать это в очередях. Вероятно, вы перейдете через строки CSV-файла, построите запрос как большой запрос WHERE id = 1 OR id = 2...
и каждые 100 строк или около того (или 50, если это еще слишком большой), запустите запрос и запустить новый для следующих 50 идентификаторов.
Или вы можете просто запустить 50.000 одиночных запросов UPDATE
в своей базе данных. Честно говоря, если таблица должным образом использует индексы, то для большинства современных веб-серверов выполнение всего 50 000 запросов займет всего несколько секунд. Даже самые загружаемые серверы должны иметь возможность обрабатывать это через минуту.
Что касается чтения файла в кусках, вы можете использовать основные функции доступа к файлу PHP для этого:
$file = fopen('/path/to/file.csv', 'r'); // read one line at a time from the file (fgets reads up to the // next newline character if you don't provide a number of bytes) while (!feof($file)) { $line = fgets($file); // or, since it's a CSV file: $row = fgetcsv($file); // $row is not an array with all the CSV columns // do stuff with the line/row } // set the file pointer to 60 kb into the file fseek($file, 60*1024); // close the file fclose($file);
Это не будет читать полный файл в памяти. Не уверен, что у Laravel есть собственный способ работы с файлами, но это как сделать это в базовом PHP.
В зависимости от данных, которые вы должны обновить, я бы предложил несколько способов:
Чтобы избежать утечки памяти, мое мнение такое же, как у @ rickdenhaan's. Вы должны читать csv по fgetcsv
используя fgetcsv
Чтобы избежать возможных тайм-аутов, например, вы можете поместить обработку скриптов в очереди laravel