MySQL 嵌套连接排序

Posted

技术标签:

【中文标题】MySQL 嵌套连接排序【英文标题】:MySQL nested join ordering 【发布时间】:2016-07-27 10:50:04 【问题描述】:

我正在尝试获取按上次活动排序并分页的“活跃”用户列表。我最初将它用作基本连接,但是当我添加了几十万测试用户时,查询会随着分页而变得越来越长,并且在您到达最后一页时会花费绝对时间。

然后我嵌套连接以解决速度问题,但由于外部查询仅返回具有偏移量和限制的活动用户,然后才能应用订单,因此我无法正确排序结果。

这是当前查询;

$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 表非常广泛,所以我不会放在这里。虽然它是相当标准的。

users.last_active 上有一个索引。

【问题讨论】:

注意LEFT JOIN y ... WHERE y ... [IS NOT NULL]INNER JOIN y ON...一样 【参考方案1】:

(我无法清楚地理解你的查询。你能把表定义吗?)

这里有一些提示:

您的 ORDER BY/LIMIT 应该在顶部选择而不是在子选择中。

如果您想通过 order by/limit 在分页上实现稳定的查询时间,您必须使用索引进行 order by。

我认为您的请求可以很容易地重写为不使用子查询和/或您可以创建适当的索引。

如果您无法重写您的选择,请使用一个表格,您将每 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 上创建索引

【讨论】:

我编辑了我的问题。 users.last_active 上已经有一个索引。您的查询几乎是我开始时的查询,运行查询以显示最后一页需要 46 秒。我正在尝试做的事情应该很简单,但由于某种原因似乎并非如此。 尝试不加入角色。几点了? 您可以存储 last_active 值的最后最小值以缩小范围 last_active 索引的基数是多少?以及行数? 抱歉问,因为我想确定:role_id 字段是否有单独的索引,或者至少在第一个索引列的字段中。

以上是关于MySQL 嵌套连接排序的主要内容,如果未能解决你的问题,请参考以下文章

Nexus-prisma:排序嵌套连接

Mysql按多行总和/或嵌套总和排序?

排序通过3个表MYSQL

Linux——MySQL高阶语句杂而精

Linux——MySQL高阶语句杂而精

Spring Data Rest - 按嵌套属性排序