代码之家  ›  专栏  ›  技术社区  ›  Harutyun Drnoyan

MySQL查询随机缓慢

  •  1
  • Harutyun Drnoyan  · 技术社区  · 12 年前

    我有一个在vBulletin系统中运行的查询,它获取具有图像附件的最新线程,以及它们的第一个附件ID。

    以下是查询:

    SELECT  thread.threadid, 
              thread.title, 
              thread.postuserid, 
              thread.postusername,
              thread.dateline, 
              thread.replycount, 
              post.pagetext,
              (
                SELECT attachment.attachmentid
                FROM `vb_attachment` AS attachment
                    LEFT JOIN `vb_filedata` AS data 
                        ON data.filedataid=attachment.filedataid
                WHERE attachment.contentid=thread.firstpostid
                    AND attachment.contenttypeid=1
                    AND data.extension IN('jpg','gif','png')
                    AND data.thumbnail_filesize>0
                ORDER BY attachmentid ASC
                LIMIT 1
              ) AS firstattachmentid
    FROM `vb_thread` AS thread
       LEFT JOIN `vb_post` AS post 
            ON post.postid=thread.firstpostid
    WHERE thread.forumid IN(331, 318)
            HAVING firstattachmentid>0
    ORDER BY thread.dateline DESC
    LIMIT 0, 5
    

    您可以在此处看到查询的解释结果:

    enter image description here

    问题是:查询通常在0.00001秒内运行,所以几乎是即时的,因为它是优化的查询,但是,在创建新线程之后( 即使线程不是来自论坛ID 331、318 ),它需要40多秒(直接从MySQL GUI执行),并且 甚至解释查询也需要2秒以上! 。解释查询慢显示与索引使用相同的结果。

    在运行相同的查询两三次之后,它又恢复到了正常速度。

    如果有人能解释发生了什么,以及如何解决这个问题,我将不胜感激。

    谢谢

    1 回复  |  直到 12 年前
        1
  •  0
  •   cja    12 年前

    MySQL缓存查询的结果,以便以后更快地返回同一查询的结果。

    添加新线程会导致MySQL在下次运行查询时必须重建查询缓存。

    我发现MySQL子查询的性能很差。我使用了一些策略来避免子查询:

    1. 将查询重新构造为不带子查询的联接。
    2. 将查询重新构造为多个查询。
    3. 返回您需要的更多数据,然后在应用程序中对这些数据进行一些处理。