【问题标题】:MYSQL higher LIMIT offset slow the queryMYSQL 较高的 LIMIT 偏移量会减慢查询
【发布时间】:2013-03-17 19:13:56
【问题描述】:

我有以下 Mysql 查询。这是一个缓慢的查询,大约需要 3 秒才能完成。 message_id 是主键。这个问题是高 LIMIT 偏移量LIMIT 85075, 25

SELECT * FROM `phorum_messages` WHERE 1  and `catergory` >=0 and parent_id=0   order by `message_id` desc  LIMIT 85075, 25;

基于this solution,我将查询改为如下方式。问题是如果我删除where parent_id=0,速度会快得多。但我真的需要where parent_id=0

编辑:我已经为 parent_id 和 message_id 创建了索引。

有什么建议吗?提前致谢。

SELECT  t.*
FROM    (
        SELECT  message_id
        FROM    phorum_messages where parent_id=0
        ORDER BY message_id desc LIMIT 85075, 25
        ) q
JOIN    phorum_messages t
ON      t.message_id = q.message_id

【问题讨论】:

    标签: mysql sql-order-by limit mysql-slow-query-log


    【解决方案1】:

    (parent_id, message_id) 上创建一个复合索引并稍微重写您的查询:

    SELECT  t.*
    FROM    (
            SELECT  message_id
            FROM    phorum_messages
            WHERE   parent_id = 0
            ORDER BY
                    parent_id DESC, message_id DESC
            LIMIT   85075, 25
            ) q
    JOIN    phorum_messages t
    ON      t.message_id = q.message_id
    

    【讨论】:

    • 我在 Phpmyadmin 中尝试过,“显示第 0 - 24 行(总共 25 行,查询耗时 1.1760 秒)”似乎仍然不快。我在 parent_id、message_id 上创建了一个复合索引
    • @Sop:你不能让它即时,而不是大的OFFSET + LIMIT。请发布查询计划。
    • 我忘了说我在 phorum_messages 表中总共有 204,407 行。
    • id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> ALL NULL NULL NULL NULL 25 1 PRIMARY t eq_ref PRIMARY,message_id PRIMARY 4 q.message_id 1 2 DERIVED phorum_messages ALL parent_id,parent_id_2 parent_id_2 4 204408 Using filesort
    • 我不知道如何发布查询计划。
    【解决方案2】:

    当使用较大的 LIMIT 偏移量时,有时最好使用不使用 LIMIT 偏移量的不同方法。

    对于第一个查询使用

    SELECT * FROM `phorum_messages`
    WHERE `catergory` >=0 and parent_id=0 
    order by `message_id` desc 
    LIMIT 25
    

    并将最低的 message_id 保存为 $min_id

    下一个通话: 然后就可以调用了

    SELECT * FROM `phorum_messages`
    WHERE `catergory` >=0 and parent_id=0  AND message_id < $min_id
    order by `message_id` desc 
    LIMIT 25
    

    获取接下来的 25 个结果。将 $min_id 设置为您从结果集中获得的最小 message_id。转到 next_call。

    【讨论】:

    • 谢谢迈克尔,这是这个问题的解决方案。我不确定还有其他答案。
    • 我将此查询用于论坛消息的单独页面。我无法创建页面 NO。 789 不知道 message_id。您的方法需要随后创建所有页面
    【解决方案3】:

    您有关于 parent_id 或 category_id 的索引吗?它会进行全表扫描,因为您在搜索字段上没有索引。 除了发回数据(在执行阶段之后)之外,具有限制的查询需要几乎相同的时间。

    【讨论】:

      【解决方案4】:

      您可以在 parent_id 列上创建索引以加快查询过程

      CREATE INDEX indexName ON phorum_messages (parent_id);
      

      【讨论】:

      • 是的更多索引,我认为它们并不重要,直到它将我的外部加入调用从 10 分钟缩短到
      • parent_idmessage_id 我认为应该在同一个索引中,因为它们都在这个查询中使用。但我不擅长数据库。
      • 对不起,我忘了提到我已经为 parent_id 创建了索引
      • 您还应该在类别中建立索引以针对此查询进行优化
      • @Sop 但是对于哪些字段,您的索引可以包含多个字段。您应该将 category 和 parent_id 和 message_id 一起索引并如上所述
      猜你喜欢
      • 2011-05-27
      • 2010-11-17
      • 2012-05-30
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-13
      相关资源
      最近更新 更多