MySQL - 确定要使用的索引,并且不能按预期工作

时间:2017-03-25 23:45:14

标签: mysql indexing

我在这里遇到两个问题,我正试图解决。首先,查询,用值替换?因为我正在使用准备好的声明:

SELECT  *
    FROM  Messages t
    WHERE  perspective_user=?
      and  timestamp BETWEEN ? AND ?
      AND  timestamp_added = 
        ( SELECT  max(timestamp_added)
            from  Messages t2
            where  t2.author = t.author
              AND  t2.body = t.body
              AND  t2.timestamp = t.timestamp
              AND  t2.timestamp_added <= ?  )
      AND  convo_id IN (
        SELECT  convo_id
            FROM  Conversations
            WHERE  perspective_user=?
              AND  identity=?
              AND  timestamp_added=? );

代码非常慢,但没有以下行。包含它,它返回0结果:

      AND  convo_id IN (
        SELECT  convo_id
            FROM  Conversations
            WHERE  perspective_user=?
              AND  identity=?
              AND  timestamp_added=? );

该行本身可以正常工作,并且有些行满足上述要求以及该行。我想知道它为什么表现得那么奇怪。

我想知道的另一件事是要添加的索引。我的第一个想法是三个索引:一个在perspective_user,timestamp,timestamp_added和convo_id上,另一个是关于author,body,timestamp和timestamp_added的索引,以及关于perspective_user,identity和timestamp_added的最终索引。

我真的不懂MySQL,所以我不确定如何继续。

2 个答案:

答案 0 :(得分:0)

你只能在t上的外部SELECT上交叉引用convoid,而不是t2上的内部SELECT。

此外,您可以通过对时间戳进行排序,降序,然后抓住第一行来逃避 - 然后您可以完全取消“t2”。

答案 1 :(得分:0)

IN ( SELECT ... )是一个非常低效的MySQL构造。而是JOIN Conversations ON convo_id = ... WHERE ...

added游戏似乎是&#34; groupwise max&#34;。有关实现此目的的有效方法的讨论,请参阅this

请提供SHOW CREATE TABLE。如果body不是TEXT,那么您需要INDEX(author, body, timestamp, timestamp_added)。如果这不起作用,那么我们需要更好地理解Messages的结构。