按照我在这个帖子PHP MySQL Query to get most popular from two different tables
上的答案我定时查询,并在调用此查询时遇到令人不安的时间。我超过8秒。 afrostarvideos表有大约2000条记录,afrostarprofiles大约300条记录。即使将查询限制为只有五个。转到http://www.veepiz.com/index.php并在热门艺术家的指导下查看这一代时间。请帮助优化此查询
//Get current time
$mtime = microtime();
//Split seconds and microseconds
$mtime = explode(" ",$mtime);
//Create one value for start time
$mtime = $mtime[1] + $mtime[0];
//Write start time into a variable
$tstart = $mtime;
$q= "SELECT `p`.*, SUM(`v`.`views`)+`p`.`views` AS `totalViews` FROM `afrostarprofiles` `p` LEFT OUTER JOIN `afrostarvideos` `v` ON `p`.`id` = `v`.`artistid`".
"GROUP BY `p`.`id` ORDER BY SUM(`v`.`views`)+`p`.`views` DESC LIMIT $pas_start,$end";
$r=mysql_query($q);
//Get current time as we did at start
$mtime = microtime();
$mtime = explode(" ",$mtime);
$mtime = $mtime[1] + $mtime[0];
//Store end time in a variable
$tend = $mtime;
//Calculate the difference
$totaltime = ($tend - $tstart);
//Output result
printf ("Page was generated in %f seconds !", $totaltime);
答案 0 :(得分:6)
要知道的第一件事 - 只要您有ORDER BY
,LIMIT
就无法帮助您。
一旦MySQL意识到它需要在结果限制它们之前对结果进行排序,它必须通过整个表来获取所有结果才能为它们命令(然后限制它们)。
那就是说(并且没有看到EXPLAIN
的查询[这将是有用的]),我猜大部分时间都是LEFT JOIN
。
确保 afrostarprofiles.id 上有索引(我猜它是主键,所以你很好)和 afrostarvideos.artistid 。< / p>
此外,除非您想要在第二次加入时没有匹配的艺术家时获得结果,否则我建议您尝试使用JOIN
(也称为INNER JOIN
)而非{{{} 1}}。
答案 1 :(得分:0)
根据上一个问题,您应该缓存此查询,因为它是最受欢迎的东西,可能不需要始终保持最新状态。我这样做是为了我的一个网站,热门的东西,创造甚至是有趣的!一个小问题,您需要在服务器上使用 crontab 之类的东西来命令脚本运行此查询。总而言之,我希望你可以缓存这种东西,因为它在服务器上要好得多。
我希望我有所帮助。
答案 2 :(得分:0)
其他人已经回答了大部分问题,但我会在大型表格的任何“聚合”或数据处理操作的“设计”方面添加更多内容永远会伤害表现。没有什么是免费的:)预建它们可能不是一个坏主意(相当不错)。
预建
的选择很少选项的选择可能取决于您的整体申请,业务规则和期望的结果。