0

私は2つのテーブルを持ってい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

ここまでは順調ですね。('using 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で、一時テーブルが原因でクエリが遅くなります。

だから(最後に)、私の質問は次のとおりusing temporaryです。

4

1 に答える 1

2

MySQL DOES offer a clause "STRAIGHT_JOIN" which tells it to do the join between tables in the order you've provided. Since you are looking for a single specific "Follower User" put the follower table up front and join from that... Try something like

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

This should FORCE Starting with the "Followers" table, specific for user ID = X, then join out to the users table as SECONDARY based on the rows returned from f.user = X. Make sure your Followers table has an index where "user" is in the first position (in case your index on both columns was (follows, user), it SHOULD be (user, follows). The smallest granularity on your query basis is the one person inquiring about... that comes in FIRST.

于 2012-01-05T18:28:16.960 に答える