我如何检查记录是否存在于表从10亿行表


How do I check if record exists in table from a 1 Billion rows table

我有一个数据抓取脚本。

它运行并擦除记录,保存到一个有10列的表中。

对于DB中已经存在的记录,如果过去2天没有更新,我需要更新旧记录。

我的表有字段scraper_run_inserted(插入记录时的DATETIME值)和scraper_run_updated(更新记录时的DATETIME值)

这个表有10亿行,

当脚本启动时,我得到所有不需要更新的记录。

THIS QUERY TAKES SO LONG…

$doNotupdateLicencesList = "SELECT DISTINCT(licence_id) FROM `{$onegov_main_table}` WHERE scraper_run_updated >= '{$prev_date_to_check}'";
$doNotupdateLicencesList = $conn->prepare($doNotupdateLicencesList);
$doNotupdateLicencesList->execute();
$doNotupdateLicencesList = $doNotupdateLicencesList->fetchAll(PDO::FETCH_COLUMN);

$doNotupdateLicencesList数组我有所有的记录,我不想更新。

我的scraper遍历网站的页面并从每个页面抓取列表licence_ids

这个数组$allLicencesOnThisPage保存了特定页面上的所有许可证。

这就是我做的…

这个循环太长

foreach ($doNotupdateLicencesList as $licence_id) {
    if (isset($allLicencesOnThisPage[$licence_id])) {
        unset($allLicencesOnThisPage[$licence_id]);
    }
}

我需要做什么来优化代码?

在抓取期间,我是否应该为每个条目对数据库进行SELECT查询,以检查是否存在并且在过去2天内没有更新?

你可能需要采取两步来加快速度:

首先,修改查询以获取过去2天内未插入或未更新的许可证:

SELECT DISTINCT(licence_id) FROM `{$onegov_main_table}` 
   WHERE scraper_run_inserted < DATE_SUB(CURDATE(), INTERVAL 2 DAY) 
   AND scraper_run_updated < DATE_SUB(CURDATE(), INTERVAL 2 DAY)

其次,您希望在将要查询的所有表上创建索引以加快查询速度。这只需要做一次。

ALTER TABLE {table_name} ADD INDEX license_insert (`licence_id`, `scraper_run_inserted`, `scraper_run_updated`);

这两个步骤将减少查询时间和需要检查的许可证数量。如果没有大量的许可证,那么您也可以将其添加到查询中并删除PHP循环。

SELECT DISTINCT(licence_id) FROM `{$onegov_main_table}` 
   WHERE scraper_run_inserted < DATE_SUB(CURDATE(), INTERVAL 2 DAY) 
   AND scraper_run_updated < DATE_SUB(CURDATE(), INTERVAL 2 DAY) 
   AND licence_id NOT IN (*comma separated list of IDs here*)