Radius SQL查询 - 优化

时间:2018-04-05 07:51:02

标签: mysql sql freeradius radius

我根本不是SQL大师,但我有一个在小型FreeRadius服务器上自动使用的SQL查询。现在我们想在更大的服务器上使用它,但我注意到查询需要很长时间,并且使用CPU 100%大约两分钟......

有没有人知道如何优化查询?目标是查找用户是否有多个活动登录,并获取最早的登录信息。

我们还可以接受更多结果,并在PHP中进行排序,以减少radius-database上的负载。

以下是我们今天使用的查询:

  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

此致

3 个答案:

答案 0 :(得分:0)

删除子查询

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的所有行

答案 1 :(得分:0)

我认为我们可以在整个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值。

答案 2 :(得分:0)

查询响应是100%正确的,您应该能够通过一次传递完成此操作。然而2分钟是疯了!我也怀疑单次通过这不是你想要的那么快。 我们有一个状态页面,可以显示所有在任何特定时刻都在线的用户,因为支持原因听起来这与您尝试的相似。

首先确保你有acctstoptime的索引。 我还怀疑你在MYSQL配置中有一些不好的配置来处理这个庞大的表。 我还强烈建议做一个存档数据库,并将所有活动会话保存在一个小数据库中,这将有助于大量更新和插入免费的半径记帐。

我们每天有超过100,000名活跃用户,临时更新为300秒,每年产生大约30亿行。我们的每一个查询都不到1秒。我很乐意帮助您优化您的自由半径。