0

基础知识:我有一个统计访问者的脚本。一些有用的信息存储在 MySQL 数据库中。现在一年多后,我有超过 180'000 条数据记录,读取实际访问者的脚本非常慢。

我有这个脚本来计算访问者并检查它是同一访问者还是新访问者。为此,我有一个 3 小时的时间范围,只有在这个范围之后,访问才会计算另一个时间。

脚本:

$besucher_query = mysql_query('SELECT `time`, `agent` FROM `besucher` ORDER BY `ip` ASC');
while($besucher = mysql_fetch_array($besucher_query)) {
    $newtime = $besucher['time'];
    $newagent = $besucher['agent'];
    $limit = 3 /*std*/ * 60 /*min*/ * 60 /*sek*/; // three hours before same visitor counts again
    $diff = $newtime - $limit;

    if($oldtime <= $diff or ($oldtime > $diff and $newagent != $oldagent))
        $besucherzahl++;

    $oldtime = $besucher['time'];
    $oldagent = $besucher['agent'];
        }
$anzahl_besucher = $besucherzahl;
echo $anzahl_besucher;

几年前我创建了这个脚本,我知道这是最丑陋的方法。时间以 UNIX Timestamp 格式存储。

现在我的问题是:如何直接在 MySQL 中将其与上述条件(3 小时规则)“分组”?

4

2 回答 2

1

您可以直接从您的 PHP 脚本执行以下查询,以获取过去 3 小时内的唯一身份访问者总数:

SELECT COUNT(DISTINCT `agent`) AS visitor_count
FROM `besucher`
WHERE `time` >= DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 3 HOUR);
于 2012-07-23T14:33:48.327 回答
0
GROUP BY 10800*FLOOR(`time`/10800)

但是,如果您在 2:59 和 3:01 有记录(例如),这些记录将在输出中报告为 2 个单独的记录。如果您想测量连续运行,那么您需要执行与当前代码类似的操作 - 但是您可以将结果存储在数据库中以免再次计算它们 - 只需添加一个引用指定为的行的新列会议开始:

ALTER TABLE besucher ADD COLUMN session_start INTEGER;

然后....

$limit = 3 /*std*/ * 60 /*min*/ * 60 /*sek*/;

$since=(integer)(file_get_contents('lastrun'))-$limit;
$besucher_query = mysql_query('SELECT 
      ip, `time`, `agent` FROM `besucher`
      WHERE `time`>$since 
      ORDER BY agent, ip, `time` ASC');
while($besucher = mysql_fetch_array($besucher_query)) {
   $newtime = $besucher['time'];
   $newagent = $besucher['agent'];
   $newip = $besucher['ip'];

   if ($newagent!=$oldagent 
       || $newip <> $oldip 
       || $newtime>$oldtime+$limit 
       || $newtime<$oldtime) {
     $sessionstart=$newtime;
   }
   $newagent=mysql_real_escape_string($newagent);
   mysql_query(
      "UPDATE besucher SET session_start=$sessionstart
       WHERE time=$newtime AND ip=$newip AND agent='$newagent'"
   );
   $oldtime = $besucher['time'];
   $oldagent = $besucher['agent'];
}
file_put_contents('lastrun', $oldtime);

然后,您可以从(例如)...获取会话数。

SELECT COUNT(*)
FROM 
(SELECT DISTINCT ip, agent, session_start
  FROM bessucher
  WHERE time BETWEEN $a AND $b) ilv

一个更简单的解决方案是在您的代码中使用会话管理并立即填充它。

于 2012-07-23T14:50:46.150 回答