我正在尝试获取一个"活跃"的列表用户按其上次活动排序并分页。我最初将它作为一个基本的连接工作,但是当我添加了几十万个测试用户时,查询将花费更长的时间进行分页并在到达最后一页时花费绝对的年龄。
然后我嵌套了连接来修复速度问题,但我无法正确排序结果,因为外部查询只返回具有偏移和限制的活动用户,然后才能应用订单。
这是当前的查询;
$sql = "SELECT * FROM (
SELECT roles_users.*, users.last_active FROM roles_users, users
WHERE roles_users.role_id = '2'
LIMIT $offset, $limit
) AS role
LEFT JOIN users ON users.id = role.user_id
WHERE
users.f_name IS NOT NULL
AND users.city IS NOT NULL
AND users.gender IS NOT NULL
AND users.date_of_birth IS NOT NULL
ORDER BY users.last_active DESC";
这样做的最佳方式是什么,以便它有效运行并正确订购?
修改
roles_users的表结构;
#-- Field -- Type ----------- Null -- Key --- Foreign key --#
#
# user_id int(10) unsigned No primary users.id
# role_id int(10) unsigned No primary user_roles.id
#
#############################################################
用户表非常广泛,所以我不会把它放在这里。这是相当标准的。
users.last_active上有一个索引。
答案 0 :(得分:0)
(我无法清楚地理解你的查询。你能把表定义吗?)
以下是一些提示:
您的ORDER BY / LIMIT应位于顶部,而不是在子选择中。
如果您希望通过/限制订单实现稳定的查询时间,则必须使用索引来获取订单。
我认为您的请求可以很容易地重写为不使用子查询和/或您可以创建适当的索引。
如果您无法重写您的选择,请使用表格,您将每隔N分钟填充一次,并使用相应的索引查询结果,并使用此表格检索数据。也许物化视图可以解决问题。
https://dba.stackexchange.com/questions/86790/best-way-to-create-a-materialized-view-in-mysql
编辑:
SELECT roles_users.*, users.last_active FROM roles_users, users
WHERE users.id = role.user_id
AND roles_users.role_id = '2'
AND users.f_name IS NOT NULL
AND users.city IS NOT NULL
AND users.gender IS NOT NULL
AND users.date_of_birth IS NOT NULL
ORDER BY users.last_active DESC
LIMIT 0, 100
在users.last_active
上创建索引