Задать вопрос

Как ускорить обновление 700K записей из файла?

Имеется файл примерно на 700 000 записей, мне необходимо периодически его проверять, если есть изменения то делаю update в базу,если нет то записываю в базу. Нужно как то ускорить этот процесс. и я не понимаю как сохранять это дело в моем случаи. уперся вот на этом моменте. не судите строго я новичок. Надеюсь код лучше объяснит.
DB::table('resources')->select('hash')->orderBy('id')->chunk(50000,
            function ($resources) use ($file, $updatedDate) {
                $lineCount = 1;
                echo 1 . '<>';

                while (!feof($file)) {
                    $line = iconv('cp1251', 'utf-8', fgets($file));
                    $csv = str_getcsv($line, ';');

                    if (count($csv) === 6) {
                        $ipPool = explode('|', $csv[0]);
                        foreach ($ipPool as $ip) {
                            $date = new \DateTime($csv[5]);
                            $hash = md5($csv[1] . $csv[2]);

                            foreach ($resources as $resource) {
                                if ($hash === $resource->hash) {
                                    DB::table('resources')->where('hash', $hash)->update([
                                        'version_date' => $updatedDate,
                                    ]);
                                    echo $lineCount++ . "<br>"  ;
                                }
                                // тут нужно записать если такой записи нет
                            }
                        }
                    }

                    $lineCount++;
                }
            });
  • Вопрос задан
  • 543 просмотра
Подписаться 4 Простой 2 комментария
Решения вопроса 1
@rockstardavid
Go/PHP
Во-первых, почему выдергиваете записи именно по 50 000? Чувстую цифра стоит рандомная.

Короче супер оптимизация, прирост в разы гарантирую - достаете все записи из бд, собираете временную хешмапу, при этом убираете лишние orderBy, которые вам не нужны
$map = [];
DB::table('resources')->select('hash')->chunk(50000,
            function ($resources) {
                    $map[$resource->hash] = $resource; // сюда можнок класть только действительно необходимые данные, чтобы память не засрать
                }
            });


потом пробегаетесь по всему файлу
while (!feof($file)) {
                    $line = iconv('cp1251', 'utf-8', fgets($file));
                    $csv = str_getcsv($line, ';');

                    if (count($csv) === 6) {
                        $ipPool = explode('|', $csv[0]);
                        foreach ($ipPool as $ip) {
                            $date = new \DateTime($csv[5]);
                            $hash = md5($csv[1] . $csv[2]);
                            
                            if (isset($map[$hash]) {
                                // запись существует, делаете апдейт
                            } else {
                                // записи нет, добавляете в свою таблицу
                            }
                        }
                    }


Только представим, что у ваc идеальная хеш-функция без коллизий...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
alex-1917
@alex-1917
Если ответ помог, отметь решением
сначала файл скачивается с другого источника, потом мне нужно проверить записи те в что в файле со своими записями,

вот ключ!
если я правильно понял из вашего сумбурного текста - вы сравниваете два ФАЙЛА?? ооооо
ЗАЧЕМ?
быстрее и проще и более способствует автоматизации - сравнивать в БД!
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы