我的
users
表列出了所有用户:
id | 名字 |
---|---|
1 | 爱丽丝 |
2 | 鲍勃 |
我的
users_teams
表定义了哪些用户属于哪些团队。
id | 团队 ID | 用户ID |
---|---|---|
1 | 100 | 1 |
2 | 100 | 2 |
我想搜索具有特定名称的用户,并且还知道他们属于哪个团队。
我首先选择用户,这是一个简单的索引查询,有10行:
EXPLAIN SELECT * FROM users
WHERE name LIKE "%bob%"
ORDER BY id DESC LIMIT 10
选择类型 | 桌子 | 类型 | 行 | 额外 |
---|---|---|---|---|
简单 | 用户 | 索引 | 10 | 使用地点 |
但是如果我尝试
LEFT JOIN
,查询解释看起来会更糟糕:
EXPLAIN SELECT u.id, t.team_id FROM users u
LEFT JOIN users_teams t ON u.id = t.user_id
WHERE u.name LIKE "%bob%"
ORDER BY u.id DESC LIMIT 10
选择类型 | 桌子 | 类型 | 行 | 额外 |
---|---|---|---|---|
简单 | 你 | 全部 | 999999 | 使用地点;使用临时的;使用文件排序 |
简单 | t | 全部 | 1234 | 使用地点;使用连接缓冲区(平面、BNL 连接) |
我只想获取这 10 行,然后对于每一行都知道该用户属于哪个团队(如果有的话)。执行此操作的最佳查询是什么?
我认为问题在于它在搜索
%bob%
之前进行连接,然后限制结果。 join需要计算一个很大的中间表。
尝试加入执行限制的子查询。
SELECT u.id, t.team_id
FROM (
SELECT *
FROM users
WHERE name LIKE '%bob%'
ORDER BY id DESC
LIMIT 10
) AS t
LEFT JOIN users_teams t ON u.id = t.user_id
ORDER by u.id DESC