繁体   English   中英

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

[英]Avoid MySQL 'using temporary' in certain cases

我有两个表, usersfollowers

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

到现在为止还挺好。 (“使用何处”是由于我为了简洁而删除的其他一些条款)。

但是,当用户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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM