相当于一个查询中的PHP循环


Equivalent of a PHP loop in possibly one query

我有一个名为"Visits"的表,它存储MAC地址及其时间戳。我的任务是将每天的MAC地址与前几天的MAC地址进行核对,如果发现,请在今天的记录中将其更新为"重复",并显示到目前为止的访问次数(不包括今天)。

我已经写了下面的PHP代码,它做得很好,但问题是,今天执行需要586.4秒(检查1500个MAC与前40天的70000个MAC),而且肯定会一天比一天糟糕。

$STH = $DBH->prepare("SELECT DISTINCT MAC FROM `Visits` WHERE TimeStamp=:TimeStamp");
$STH->bindParam(':TimeStamp', $unixDataDate);
$STH->execute();
while ($r = $STH->fetch(PDO::FETCH_ASSOC)) {
    $MAC=$r['MAC'];
    $STH2 = $DBH->prepare("SELECT COUNT(ID) FROM `Visits` WHERE MAC=:MAC AND TimeStamp<:TimeStamp");
    $STH2->bindParam(':MAC', $MAC);
    $STH2->bindParam(':TimeStamp', $unixDataDate);
    $STH2->execute();
    $prevVisits=$STH2->fetchColumn();
    if ($prevVisits>0) {
            $STH3 = $DBH->prepare("UPDATE `Visits` SET RepeatVisitor=:RepeatVisitor WHERE MAC=:MAC AND TimeStamp=:TimeStamp");
            $STH3->bindParam(':RepeatVisitor', $prevVisits);
            $STH3->bindParam(':MAC', $MAC);
            $STH3->bindParam(':TimeStamp', $unixDataDate);
            $STH3->execute();
    }
}

现在,我尝试了几种方法来构造一个查询来完成这项工作并比较执行时间,但都无法得到相同的结果。对于是否可以在一个廉价的查询中完成这项任务以及如何格式化它,我们将不胜感激。

我假设Visits.TimeStamp是一个日期

UPDATE Visits 
SET RepeatVisitor = 
(SELECT COUNT(*) FROM Visits as v2 WHERE v2.MAC = Visits.MAC and v2.TimeStamp!=Visits.TimeStamp AMD v2.TimeStamp>'[40 days ago generated in PHP]') 
WHERE Visits.TimeStamp = '[Yesterday generated in PHP]'

您是否在MAC列和时间戳列上都放置了索引?如果没有,这些应该会大大加快速度。

此外,将prepare语句移到while循环之外,您正在一遍又一遍地准备相同的查询,这有点没有切中要害。准备一次,执行更频繁。