Во-первых, почему выдергиваете записи именно по 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 идеальная хеш-функция без коллизий...