Быстрый поиск разницы файлов
Ну собственно это история одной маленькой победы, которые происходят обычно у ИТишников каждый день 😉
Предыстория: при работе скрипта по заливке данных в БД из файла произошло зависание сервера. Скрипт работал в несколько потоков с одним файлом. Потому определить на каком именно месте файла произошла остановка не представлялось возможным. Удалять уже залитое в БД и стартовать скрипт заново — не вариант, скрипт и так работал двое суток, и терять их снова — ну так себе решение.
Решение №1. «В лоб». Ну думаю доработаю скрипт так, что если данные уже есть, то просто пропускаем. Т.е. перед вставкой выполняем проверку функцией вида:
function lsYet($period,$ls){
global $db;
$res=false;
$sql="select posting_addresses.id from posting_addresses
inner join ls on ls.id=posting_addresses.ls
where
posting_addresses.period='$period' and ls.ls='$ls'";
$query = $db->connection->prepare($sql);
$query->execute();
while ($row99 = $query->fetch()) {
$res=true;
};
return $res;
}
И без проблем дозальем то, чего нет в БД. Да не тут то было, оказывается операция select в этом случае весьма дорогостоящая, и т.к. в БД записей порядка 600тыс, и индексы проставлены на ls и period корректно, но всёж скорость проверки крайне низкая, и т.о. скорость «дозалития» сокращается с двух суток до суток. Ну что собственно не устраивает.
Решение №2. Вдумчивое. Решил было выгрузить ключевые строки (лицевой счет) в файлы: файл ls_in_base.txt — лицевые счета которые уже в БД и ls_all.txt — файл со всеми лицевыми счетами, которые должны быть в БД, отсортировав их командой sort:
sort ls_in_base.txt > ls_in_base.txt
sort ls_all.txt > ls_all.txt
Далее воспользуемся Linux командой comm, вычленив уникальные записи файла ls_all которые не содержаться в файле ls_in_base:
comm -23 ls_all.txt ls_in_base.txt > no_in_base.txt
И далее уже в скрипте вместо проверки наличия лс в БД при помощи запроса, проверяем наличие лс в БД при помощи in_array:
$no_in_base_ls=file_get_contents("no_in_base.txt");
$no_in_base_arr=explode("\n",$no_in_base_ls);
...
if (in_array($ls, $no_in_base_arr)==true){
...
заливаем данные в БД
...
}
В результате скорость увеличилась в разы, и БД дозалить удалось в течении часа