1

私の Web サイトにアクセスするたびに、ユーザーの個々のヒット カウンターが更新time()され、Cookie に保存されている IP アドレスと ID に基づいて列が更新されます。したがって、データを出力する場合、基本的にそれ自体のコピーであるため、データベース呼び出しが少ない次のコードのより効率的な方法は次のとおりです。

<?
$last1Min = time()-60;
$last5Mins = time()-300;
$last1Hr = time()-6000;
$last1Dy = time()-144000;
$last1Wk = time()-1008000;
$last1Mnth = time()-30240000;

//last1Min
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Min";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last minute: " . $rows['COUNT(*)'] . "<br />\n";
}

//last5Mins
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last5Mins";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last 5 minutes: " . $rows['COUNT(*)'] . "<br />\n";
}

//last1Hr
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Hr";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last hour: " . $rows['COUNT(*)'] . "<br />\n";
}

//last1Dy
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Dy";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last day: " . $rows['COUNT(*)'] . "<br />\n";
}

//last1Wk
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Wk";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last week: " . $rows['COUNT(*)'] . "<br />\n";
}

//last1Mnth
$sql = "SELECT COUNT(*) FROM usersonline WHERE lastOnline > $last1Mnth";
while($rows = mysql_fetch_array(mysql_query($sql))) {
    echo "Users online in the last month: " . $rows['COUNT(*)'] . "<br /><br />\n";
}

このデータを表示するより効率的な方法がある場合は、サイト全体でこれらの指標ごとにオンラインのユーザー数を表示するだけでなく、サイトのすべてのページのデータを記録して出力するように拡張したいと考えています。 .

4

4 に答える 4

5
SELECT 
  SUM(lastOnline <= 60) AS one_minute,
  SUM(lastOnline <= 300) AS five_minutes,
  ...
  SUM(lastOnline <= 30240000) AS one_month
FROM usersonline

この方法を使用すると、1 回のテーブル スキャンで 1 回のクエリで必要なものをすべて取得できます。それよりもはるかに効率的ではありません。他の人が述べたように、結果は比較的高価であるため(この最適化された形式であっても)キャッシュする必要があります。ページの読み込みごとにこれを計算しても意味がありません。特に、1 秒間に複数のヒットがある場合 (たとえば、digg のトップページにアクセスした場合は、その可能性が非常に高くなります)

lastOnline <= 60 は、条件が true の行の場合は 1 に評価され、条件が false の行の場合は 0 に評価されます。SUM() は、これらの 1 とゼロを合計して、条件が真である行の数をカウントします。

数年前に mysql ドキュメントのユーザー コメントからこの手法を学びました。他にも似たような例がある

于 2009-05-21T00:22:55.637 に答える
3

正しい値を 1 分 / 5 分 / などに 1 回だけ計算する cron ジョブを設定します。結果をキャッシュし、代わりに表示します。これらの種類の統計が 1 分間または 30 分に 1 回しか変化しない場合、1 秒間に X 回計算する必要はありません。

于 2009-05-21T00:04:42.477 に答える
0

セッションをファイルに保存すると、一定期間にアクセスされたファイルの数を数えることができます。その後、データベースへのアクセスはまったくありません。

于 2009-05-21T00:30:06.683 に答える
0

毎回データベースを呼び出す代わりに、過去 1 か月以内のすべてのデータを呼び出して日付順に並べることができます。次に、php で日付と時刻を比較して、ユーザーが最後にログインした時間を確認できます。

于 2009-05-21T00:01:36.820 に答える