索引没有得到最佳使用

时间:2014-03-29 17:04:28

标签: mysql indexing rdbms

我有查询:

EXPLAIN SELECT talks.*, users.*
FROM (
  SELECT p_talk
  FROM posts WHERE p_user=1
  GROUP BY p_talk
  ORDER BY MAX(p_time) DESC
  LIMIT 30
) AS posts
 JOIN talks
    ON p_talk=t_id
 JOIN users
    ON t_user=u_id

我制作了一个索引“历史”:

p_user, p_time, p_talk

但我仍然得到以下EXPLAIN输出:

1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    30  
1   PRIMARY talks   eq_ref  PRIMARY,t_user  PRIMARY 4   posts.p_talk    1   
1   PRIMARY users   eq_ref  PRIMARY PRIMARY 4   channels.talks.t_user   1   
2   DERIVED posts   ref p_user,history  history 4       39320   Using where; Using index; Using temporary; Using f...

为什么它会查看与p_user匹配的每个帖子?

修改 如果我删除GROUP和ORDER,它仍会显示EXPLAIN输出中的所有39320行。这让我很困惑。为什么它会估计它将遍历所有匹配p_user = 1的行,如果我告诉它返回前30个?

1 个答案:

答案 0 :(得分:0)

在大多数数据库中,此表的最佳索引为:

p_user, p_talk, p_time

group by之前评估order by,因此该列必须首先在索引中。

我并非100%确定MySQL会利用此索引进行此查询。

编辑:

如果您确信在最近的500条记录中有足够的p_talk值,那么您可以将以下内容与现有索引一起使用:

FROM (SELECT p_talk
      FROM (SELECT p_talk, p_time
            FROM posts
            WHERE p_user = 1
            ORDER BY p_time DESC
            LIMIT 500
           ) p
      GROUP BY p_talk
      ORDER BY MAX(p_time) DESC
      LIMIT 30
     ) AS posts