2009-05-20 2 views
1

Каждое посещение моего сайта обновляет индивидуальный счетчик пользователей и обновляет столбец для time() на основе их IP-адреса и идентификатора, хранящихся в файле cookie. Поэтому, когда приходит к выводу данных, что более эффективный способ моего следующего кода с меньшим количеством обращений к базе данных, так как это по сути копия себя:Узнайте, сколько пользователей находится в сети на PHP?

<? 
$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"; 
} 

Если есть более эффективный способ представления этих данных, я 'm хочет расширить его, чтобы показать не только, сколько пользователей для каждой из этих показателей включено в сеть на моем весь сайт, но записывать и выводить данные для каждой страницы на моем сайте.

ответ

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

Используя этот метод, вы можете получить все, что вам нужно, в одном запросе с помощью одного сканирования таблицы; он не становится намного более эффективным, чем это. Как отмечали другие, вы должны кэшировать результат, поскольку он относительно дорог (даже в этой оптимизированной форме). Нет смысла вычислять это при каждой загрузке страницы, особенно если вы видите несколько обращений в секунду (что очень вероятно, если вы, скажем, попадете на первую страницу digg)

lastOnline < = 60 оценивается в 1 для строки, где условие истинно, и 0 для строк, где условие ложно; SUM() суммирует эти 1s и нули, давая вам количество строк, для которых условие истинно.

Изучил эту технику из комментария пользователя в документах mysql несколько лет назад; есть similar examples elsewhere

+0

Да, это то, что я получил после одного вызова базы данных, но, как вы говорите, будет использоваться непосредственно с заданием cron и кешем. –

0

Вместо того, чтобы звонить в базу данных в любое время, вы можете просто позвонить за все в течение последнего месяца и заказать их по дате. Затем в php вы можете сравнить дату и время, чтобы узнать, как давно последний пользователь вошёл в систему.

+0

Это похоже на прямое решение, но что было бы эффективным способом пройти через каждую запись, чтобы отсортировать ее по разным метрикам? Будет ли все еще хорошо проходить 100 000 записей? –

+1

Недостаток выполнения работы на PHP заключается в том, что вам приходится иметь дело с передачей всех этих данных на PHP через сокет; часто эта передача данных может быть довольно дорогостоящей, для больших объемов данных. Если вы можете получить свою базу данных для выполнения математики для вас и вернуть результаты, вы сэкономите много коммуникационных издержек. –

+0

вам не нужно сравнивать каждую запись. Вы можете использовать двоичный поиск, чтобы найти, где точка останова для каждого отдельного времени, которое вы хотите отобразить. –

3

Настройте задание cron, которое вычисляет правильные значения только раз в минуту/5 минут/и т.д. Вместо этого скопируйте результат и покажите это. Нет необходимости рассчитывать эти виды статистики X раз в секунду, когда они меняются только один раз в минуту или один раз в полчаса.

+0

Это хороший момент и фокусируется на периодических вызовах, а не для КАЖДОГО посещения, которое может быть тысячами, поэтому я должен был подумать об этом. –

0

Если вы сохраняете свои сеансы в файлах, вы можете подсчитать количество файлов, к которым обращались в течение определенного периода времени. Тогда вообще не будет доступа к базе данных.

+0

Будет ли один файл журнала лучше?Казалось бы, неуправляемо со временем иметь 100 000 + файлов сеанса –

+0

Да, но PHP управляет этими файлами и удаляет их по истечении срока действия сеанса. – psayre23

+0

Итак, это справедливое решение, чтобы узнать, кто сейчас в сети, но нужно создать отдельные файлы сеансов, чтобы покрыть каждую метрику, в которой заканчиваются сеансы 1min, 5mins, 1hr, 1day, 1month и т. Д. –

Смежные вопросы