我根本不是SQL专家,但我有一个在小型FreeRadius服务器上自动使用的SQL查询。现在我们想在更大的服务器上使用它,但是我注意到这个查询需要很长的时间,并且使用CPU 100%的时间大约两分钟.
有人知道如何优化查询吗?目标是找出一个用户是否有一个以上的活动登录,并获取最古老的信息。
我们还可以接受更多的结果,并在PHP中进行排序,以减少radius-数据库的负载。
以下是我们今天使用的查询:
SELECT username, acctstarttime, acctsessionid, nasipaddress, framedipaddress
FROM radacct
WHERE username IN (
SELECT username
FROM radacct
WHERE acctstoptime IS NULL
GROUP BY username
HAVING COUNT(username) > 1
)
AND acctstoptime IS NULL
GROUP BY username
ORDER BY username, acctstarttime ASC问候
金姆
发布于 2018-04-05 08:02:47
我认为我们只需对整个radacct表进行一次传递:
SELECT username, MIN(acctstarttime) AS min_start_time
FROM radacct
WHERE acctstoptime IS NULL
GROUP BY username
HAVING COUNT(*) >= 2
LIMIT 0, 30;这将只返回具有两个或多个活动帐户的用户。它还将为每个用户返回最新的acctstarttime值。
发布于 2018-04-05 07:56:45
要么删除子查询
SELECT username, acctstarttime, acctsessionid, nasipaddress, framedipaddress
FROM radacct
WHERE acctstoptime IS NULL
GROUP BY username
ORDER BY username, acctstarttime ASC
HAVING COUNT(username) > 1或从外部查询中删除group by (如果您希望获得具有重复username的所有行)
发布于 2018-05-14 06:14:08
查询响应是100%正确的,您应该能够通过一次访问就可以做到这一点。然而,2分钟是疯狂的!我还怀疑用一次传球,这不是你想要的那么快。我们有一个状态页面,以显示所有的用户谁是在任何时候,因为支持的原因,听起来这是类似于你试图做的任何时刻在线。
首先,确保您有一个在止损时间上的索引。我还怀疑您在MYSQL配置中有一些糟糕的配置来处理这么大的一个表。我还强烈建议创建一个归档数据库,并将所有活动会话保存在一个小型数据库中,这将有助于大量更新和插入空闲radius会计所做的工作。
我们每天有100,000多名活跃用户,临时更新时间为300秒,每年产生约30亿行。我们的每一个查询都很短于1秒。我很乐意帮你优化你的自由半径。
https://stackoverflow.com/questions/49666943
复制相似问题