MySQL嵌套连接排序

时间:2016-04-06 20:00:40

标签: mysql join sql-order-by

我正在尝试获取一个"活跃"的列表用户按其上次活动排序并分页。我最初将它作为一个基本的连接工作,但是当我添加了几十万个测试用户时,查询将花费更长的时间进行分页并在到达最后一页时花费绝对的年龄。

然后我嵌套了连接来修复速度问题,但我无法正确排序结果,因为外部查询只返回具有偏移和限制的活动用户,然后才能应用订单。

这是当前的查询;

$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上有一个索引。

1 个答案:

答案 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

上创建索引