我的主页上一直有大约700-800名访客(根据分析),总体上点击量很大。然而,我希望在我的主页上显示我的用户和其他东西的实时统计数据。因此,我有这个:
$stmt = $dbh->prepare("
SELECT
count(*) as totalusers,
sum(cashedout) cashedout,
(SELECT sum(value) FROM xeon_stats_clicks
WHERE typ='1') AS totalclicks
FROM users
");
$stmt->execute();
$stats=$stmt->fetch();
然后我将其用作$stats["totalusers"]
等
table.users have `22210` rows, with index on `id, username, cashedout`, `table.xeon_stats_clicks` have index on `value` and `typ`
然而,每当我启用上述查询时,我的网站立刻变得很慢。一旦我禁用它,加载时间就会急剧下降。
否则怎么办?
您应该不要那样做。正如您现在所经历的那样,您最终将展示您宝贵的数据库资源。好的方法是在30秒或1分钟的间隔内运行一个单独的cronjob,然后将结果写入一个文件:
file_put_contents('stats.txt', $stats["totalusers"]);
然后在你的主页上
<span>current users :
<b><? echo file_get_contents('stats.txt');?></b>
</span>
美妙之处在于,HTTP服务器会缓存此文件,因此在stats.txt
更改之前,缓存中也会有一个副本。
示例,按文件保存/加载JSON:
$test = array('test' => 'qwerty');
file_put_contents('test.txt', json_encode($test));
echo json_decode(file_get_contents('test.txt'))->test;
将输出CCD_ 3。将$test
替换为$stats
,如注释所示
echo json_decode(file_get_contents('stats.txt'))->totalclicks;
据我所知,这个查询没有任何特定于网站上任何用户的内容。因此,如果您为每个发出请求的用户执行这个查询,那么您将生成数千个相同的查询。
你可以做一种类似的缓存:
创建一个基本上与此查询的输出类似的表。
制作一个PHP脚本,只执行这个查询并用最新结果更新前面提到的表。
每分钟将此PHP脚本作为cron作业执行一次,以更新统计信息。
然后,为每个请求运行的查询可以非常简单,比如:
SELECT totalusers cashedout, totalclicks FROM stats_table
从查询中,我看不出有任何真正的理由在其中使用子查询,因为它没有使用users表中的任何数据,而且这可能会减慢它的速度——如果内存充足,它会为users表(从外观上看,这是很多行)中的每一行查询xeon_ckles表一次。
尝试将其作为两个单独的查询而不是一个查询来执行。