【发布时间】:2012-02-13 12:37:36
【问题描述】:
假设您有这样的查询...
SELECT T.TaskID, T.TaskName, TAU.AssignedUsers
FROM `tasks` T
LEFT OUTER JOIN (
SELECT TaskID, GROUP_CONCAT(U.FirstName, ' ',
U.LastName SEPARATOR ', ') AS AssignedUsers
FROM `tasks_assigned_users` TAU
INNER JOIN `users` U ON (TAU.UserID=U.UserID)
GROUP BY TaskID
) TAU ON (T.TaskID=TAU.TaskID)
可以将多个人分配给给定任务。此查询的目的是为每个任务显示一行,但分配给该任务的人员在一列中
现在...假设您在tasks、users 和tasks_assigned_users 上设置了正确的索引。将tasks 加入派生表时,MySQL 优化器仍不会使用 TaskID 索引。 WTF?!?!?
所以,我的问题是……如何让这个查询使用 tasks_assigned_users.TaskID 上的索引?临时表很蹩脚,所以如果这是唯一的解决方案...... MySQL 优化器很愚蠢。
使用的索引:
- 任务
- 主要 - 任务 ID
- 用户
- 主要 - 用户 ID
- tasks_assigned_users
- PRIMARY - (TaskID,UserID)
- 附加索引 UNIQUE - (UserID,TaskID)
编辑:另外,this page 表示派生表在连接发生之前执行/实现。为什么不重复使用密钥来执行连接?
编辑 2: MySQL 优化器不允许您将 index hints 放在派生表上(可能是因为派生表上没有索引)
编辑 3: 这是一篇非常好的博文:http://venublog.com/2010/03/06/how-to-improve-subqueries-derived-tables-performance/ 请注意,案例 #2 是我正在寻找的解决方案,但 MySQL 似乎不支持这次。 :(
编辑 4: 刚刚找到this:“从 MySQL 5.6.3 开始,优化器更有效地处理 FROM 子句中的子查询(即派生表):...查询期间执行时,优化器可能会向派生表添加索引以加快从中检索行的速度。”看起来很有希望...
【问题讨论】:
-
你也可以添加你正在使用的索引吗?我假设你有一个关于任务的 PK 和一个关于 tasks_assigned_users 的非唯一索引。
-
@Luis - 为你编辑了问题:)
-
您有 GROUP BY 任务 ID,这意味着多个人可能正在处理给定的任务,这也意味着一些聚合。您是否希望分配给给定任务的所有人都列在与该任务关联的单个返回列中?或者,您是否真的希望看到每个人都分配了一项任务,而那些未分配的任务则将其留空。甚至可能将任何未分配的任务推到列表的顶部(或底部)......
-
可以将多个人分配给给定任务。此查询的目的是为每个任务显示一行,但分配给该任务的人员在一列中
-
类似问题:stackoverflow.com/questions/1180714/… 此人建议使用临时表,对其进行索引,然后运行查询。这是蹩脚的。
标签: mysql sql join derived-table optimization