在某些情况下,避免MySQL'使用临时'

时间:2012-01-05 14:22:19

标签: mysql optimization temp-tables explain

我有两个表,usersfollowers

users

id          INT, PRIMARY_KEY
name        VARCHAR
joined      INT

此表已在idjoined上编入索引。

表'追随者':

user        INT
follows     INT 

此表已在usersfollows上编入索引。

此查询查找在特定时间后加入的特定用户所遵循的所有用户的名称。结果需要 按时间倒序排列。

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

1 个答案:

答案 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”位于第一个位置(如果两列上的索引都是(跟随,用户),它应该是(用户,跟随)。查询基础上的最小粒度是一个人询问...排在第一位。