我有两个表,users
和followers
:
表users
:
id INT, PRIMARY_KEY
name VARCHAR
joined INT
此表已在id
和joined
上编入索引。
表'追随者':
user INT
follows INT
此表已在users
和follows
上编入索引。
此查询查找在特定时间后加入的特定用户所遵循的所有用户的名称。结果需要 按时间倒序排列。
SELECT u.name
FROM users u, followers f
WHERE f.user = X
AND f.follows = u.id
AND u.joined > 1234
ORDER BY u.joined DESC
现在,当用户X拥有大量关注者时,EXPLAIN会提供以下内容:
id key extra
-----------------------------------
u joined Using where
f follows Using index
到目前为止一切顺利。 ('使用where'是由于我为了简洁而删除了一些其他条款。)
但是,当用户X拥有少量关注者时,会发生这种情况:
id key extra
-----------------------------------
f follows Using temporary, using filesort
u joined Using where
如果我省略ORDER BY
,我会得到:
id key extra
-----------------------------------
f follows
u joined Using where
MySQL优化器似乎正在检查它必须处理的行数,如果它很小,那么就做了
先followers
表。它似乎忽略了优化步骤中的ORDER BY
,导致查询速度变慢
到临时表。
所以(最后),我的问题是:是否有可能强制MySQL执行表搜索的顺序,并且在可能的情况下这是不可能的,还有另一种方法来摆脱using temporary
?
答案 0 :(得分:2)
MySQL DOES提供了一个“STRAIGHT_JOIN”子句,它告诉它按照你提供的顺序在表之间进行连接。由于您正在寻找一个特定的“追随者用户”,因此请将关注者表放在前面并从中加入...尝试类似
SELECT STRAIGHT_JOIN
u.name
from
followers f
join Users u
on f.follows = u.id
and u.joined > 1234
where
f.user = X
order by
u.joined DESC
这应该FORCE从“Followers”表开始,特定于用户ID = X,然后根据f.user = X返回的行以SECONDARY的身份连接到users表。确保你的Followers表有一个索引其中“user”位于第一个位置(如果两列上的索引都是(跟随,用户),它应该是(用户,跟随)。查询基础上的最小粒度是一个人询问...排在第一位。