我有一个在 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
您可以在此处看到查询的解释结果:
问题:通常查询在 0.00001 秒内运行,所以几乎立即运行,因为它优化了整体查询,但是,在创建新线程之后(即使线程不是来自论坛 ID 331、318) ,需要 40 多秒(直接从 MySQL GUI 执行),甚至解释查询也需要 2 多秒!。 Explain query taking slow 显示关于索引使用的相同结果。
在运行同一个查询 2-3 次后,它恢复到正常速度。
如果有人能解释发生了什么,以及如何解决问题,我将不胜感激。
谢谢。
最佳答案
MySQL 缓存查询结果,以允许它稍后更快地返回相同查询的结果。
添加新线程导致 MySQL 必须在下次运行查询时重建查询缓存。
我发现 MySQL 子查询的性能很差。我用来避免子查询的一些策略:
- 将查询重组为没有子查询的连接。
- 将查询重组为多个查询。
- 返回更多您需要的数据,然后在您的应用程序中使用这些数据。
关于MySQL查询随机慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14998440/