Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 未优化使用索引_Mysql_Indexing_Rdbms - Fatal编程技术网

Mysql 未优化使用索引

Mysql 未优化使用索引,mysql,indexing,rdbms,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 我制作了一个索引“历史”: 但我仍然得到以下解释输出:

我有一个疑问:

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
我制作了一个索引“历史”:

但我仍然得到以下解释输出:

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...
1主全部空30
1个主要对话eq_ref PRIMARY,t_user PRIMARY 4个帖子。p_talk 1
1个主用户eq_ref主4个信道。talks.t_用户1
2个参考p_用户的导出帖子,历史记录439320使用where;使用指数;使用临时设备;使用f。。。
为什么它会浏览每一篇与p_用户匹配的帖子

编辑:
如果我删除了GROUP和ORDER,它仍然会显示EXPLAIN输出中的所有39320行。这使我困惑。如果我告诉它返回前30行,为什么它会估计它将遍历与p_user=1匹配的所有行?

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

p_user, p_talk, p_time
分组依据
排序依据
之前进行评估,因此列需要首先位于索引中

我不能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

我不明白你的问题。它需要查看
p\u user=1
的所有帖子。您是说它正在查看所有这些记录,还是说它正在查看所有记录,而不考虑用户
p_
?解释的第4行显示了39320行。这张桌子大约有200万张。它看起来像是在处理整个索引,其中p_user=1,而不仅仅是最上面的行,直到它有30个。但随后它必须遍历所有p_talk值。我想要最后30条没有p_talk副本的条目。@user3476232。它必须遍历所有的
p\u 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