我正在论坛上的线程页面记录信息,4天内有近400,000个条目,一个SQL查询使用12秒,如果可能,我需要帮助减少查询运行时间或使用php计算客人查看每个thread_id
我有以下mysql表和列
thread_count
count_id thread_id user_id timestamp ip_address
对于使用此查询的观看次数超过100次的主题,我已经在0.2秒内获得每周统计数据
SELECT thread_id, timestamp, user_id, COUNT(thread_id) AS cnt FROM thread_count GROUP BY thread_id HAVING COUNT( thread_id) >100 AND timestamp > UNIX_TIMESTAMP() - 24 * 3600 * 7 ORDER BY cnt DESC
问题是指我尝试运行此查询以查看有多少来宾视图
$guestcount = SELECT user_id, thread_id, COUNT(user_id) AS cntg FROM thread_count WHERE user_id =0 AND thread_id = ".$array['thread_id']."
在第一个查询的while循环中运行
第二个查询需要12.9秒才能运行
这是来自php代码的while循环,它的vbulletin可能看起来很奇怪
while ($array = $db->fetch_array($threadsql)){
$thread_title = $db->fetch_array($vbulletin->db->query_read("SELECT title FROM thread WHERE threadid = ".$array['thread_id'].""));
// $guestcount = $db->fetch_array($vbulletin->db->query_read("SELECT user_id, thread_id, COUNT(user_id) AS cntg FROM " . TABLE_PREFIX . "thread_count WHERE user_id =0 AND thread_id = ".$array['thread_id'].""));
$weekly .= '<tr><td><a href="showthread.php?t='.$array['thread_id'].'">'.$array['thread_id'].'</a></td>
<td>'.$array['cnt'].' </td> <td><a href="showthread.php?t='.$array['thread_id'].'">'.$thread_title[title].'</a></td><td>Username Here</td> <td>'.$guestcount[cntg].'</td> </tr>';
}
基本上,客户点击在 user_id 列中存储为 0 ,我确实尝试了这一点而不是使用12秒查询,但它只显示0
foreach($array as $guest){
if ($array[user_id] = 0 && $thread[thread_id] = $array[thread_id])
$guestcount = count($guest);
}
答案 0 :(得分:2)
考虑使用SQL解决方案。具体来说,由于您运行两个不同的聚合,因此使用派生表返回 thread_id , cnt , title 和 cntg 所有字段都在一个查询调用中使用嵌套循环。
此外,遗憾的是,与某些MySQL开发人员一样,您没有运行有效的ANSI SQL,因为GROUP BY
必须包含所有非聚合列,因此原始查询应该失败。可能,你关闭了MySQL的ONLY_FULL_GROUP_BY
模式(默认情况下从版本5.7.5开始)。下面的查询被调整为完全兼容的SQL,可以移植到其他RDBMS。
SELECT t.thread_id, t.cnt, h.title, g.cntg
FROM
(SELECT c.thread_id, COUNT(c.thread_id) AS cnt
FROM thread_count c
WHERE c.timestamp > UNIX_TIMESTAMP() - 24 * 3600 * 7
GROUP BY c.thread_id
HAVING COUNT(c.thread_id) > 100
) As t
INNER JOIN
(SELECT c.thread_id, COUNT(c.user_id) AS cntg
FROM thread_count c
WHERE c.user_id=0
GROUP BY c.thread_id
) As g
ON t.thread_id = g.thread_id
INNER JOIN
thread h
ON h.threadid = t.thread_id
ORDER BY t.cnt DESC