【问题标题】:MySQL - Figuring out what indexes to use, AND not working as expectedMySQL - 找出要使用的索引,并且没有按预期工作
【发布时间】:2023-04-09 06:10:01
【问题描述】:

我想解决两个问题。首先是查询,其值替换为 ?因为我使用的是准备好的语句:

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,所以我不确定如何继续。

【问题讨论】:

  • 不要在一个帖子中提出多个问题。分别询问他们。

标签: mysql indexing


【解决方案1】:

您只能在 t 上的外部 SELECT 上交叉引用 convoid,但不能在 t2 上的内部 SELECT 上交叉引用。

此外,您可能只需按时间戳排序、降序排列,然后抓取第一行 - 然后您可以完全取消“t2”。

【讨论】:

  • 查询将返回数千行,我需要它们。
【解决方案2】:

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

added 游戏似乎是“分组最大值”。请参阅this 讨论有效的方法。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多