@Mixa

Как оптимизировать SQL-запросы?

Такая тема. Есть парсер сайта. Скрипт собирает все новости на странице удаленного сайта в один массив.

Потом запускается цикл, который перебирает массив, сверяя хранящиеся в элементах массива айди новостей, с последними N записей в базе данных и, если, проверяемый айди из массива не находится в последнем N записей, то он записывается в базу с остальной информацией, хранящейся в элементе массива (текст новости, заголовок, дата и т.д.).

Умом понимаю, что под каждый элемент массива запрос из базы и сравнение каждый раз с большим количеством строк - наверное не совсем аккуратное решение. Да еще и, в случае отсутствия совпадения, добавляется еще один запрос - запись.

Как можно минимизировать количество запросов? Представляю, что можно наверное один раз вытянуть последние N записей из базы, сравнить их с массивом и подготовить массив элементов, которые не нашлись в базе, и потом один раз всего сделать запись в базу всех отсутствующих новостей. Но как это правильно реализовать - не имею опыта. Буду премного благодарен за поэтические примеры.
  • Вопрос задан
  • 95 просмотров
Решения вопроса 1
vman
@vman
На примере

$result = $dbh->query("SELECT id FROM test.news LIMIT 3")->fetchAll(PDO::FETCH_ASSOC);

// получили из БД список ID
// +-----+
// | id  |
// +-----+
// | 100 |
// | 101 |
// | 102 |
// +-----+
$exist  = [];

// делаем массив у которого ключ = ID, а значение = true
foreach ($result as $row) {
    $exist[$row['id']] = true;
}

// массив новостей
$news = [
    [ "id" => 102 , "titile" => "news title", "text" => "news text" ],
    [ "id" => 1001, "titile" => "news title", "text" => "news text" ]
];

// проходим по каждому элементу массива с новостями
foreach ($news as $key => $item) {

    // проверяем если ли в БД новость с таким ID
    if (isset($exist[$item['id']]) && $exist[$item['id']] === true) {

        // если такой новости нет - удаляем из массива с новостями
        unset($news[$key]);
    }
}


после фильтрации в новостях останется только новость с ID = 1001, ее и вставляем в БД.

Можно пойти другим путем, если ID новости является PK, или имеет уникальный ключ, то можно просто вставлять все новости игнорируя ошибки

INSERT INTO ..... ON DUPLICATE KEY UPDATE updated_at = NOW()


вставляем запись и если она уже была, обновим поле updated_at
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

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