как обрабатывать большой размер запроса на обновление в mysql с laravel

Есть Способ, которым я могу обновить 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,
    вы можете создавать несколько партий каждые X строк из csv.
  • Если каждый отдельный пользователь должен быть обновлен с уникальными значениями – вам нужно запускать отдельные запросы.
  • Если у каких-либо обновленных столбцов есть индексы – вы должны отключить автоматическую учетную запись и выполнить транзакцию вручную, чтобы избежать повторной проверки после каждого отдельного обновления.

Чтобы избежать утечки памяти, мое мнение такое же, как у @ rickdenhaan's. Вы должны читать csv по fgetcsv используя fgetcsv

Чтобы избежать возможных тайм-аутов, например, вы можете поместить обработку скриптов в очереди laravel