MySql - 添加 Order by 时查询缓慢

Posted

技术标签:

【中文标题】MySql - 添加 Order by 时查询缓慢【英文标题】:MySql - Slow Query when adding Order by 【发布时间】:2021-06-23 06:01:24 【问题描述】:

我有一个从 mysql 数据库读取电子邮件的应用程序(我从应用程序数据库中的 gmail 收件箱下载电子邮件)。并且数据库具有以下结构

表 1(联系人):

ContactID (int)
ContactName (varchar(100)
ContactEmailAddress (varchar(150))
    

表2(科目):

SubjectID (int)
ContactID (int)
Subject (varchar(200))

    

Table3(消息):

MessageID (int)
SubjectID (int)
MessageText (varchar(150)
IsRead (tinyint)
IsReceived (tinyint)
MessageDate (DateTime)

这是我获取最近 40 条记录的查询

SELECT * FROM(SELECT ROW_NUMBER()OVER(Order by isRead ASC,MessageDate DESC) RecID,
c.ContactName,s.subject,s.SubjectID,d.MessageDate,d.isRead
from Contacts c                    
INNER JOIN Subjects s on s.ContactID=c.ContactID
JOIN (
select MAX(MessageID) dtl_id,SubjectID from Messages where IsReceived=1    
GROUP BY SubjectID)d_max on (d_max.subjectid=s.subjectid)
JOIN Messages d on (d.MessageID=d_max.dtl_id)
) AS RowConstrainedResult where RecID >=1 and RecID <=40  ORDER BY RecID

但此查询需要将近 15 秒才能加载。应该做些什么来提高查询性能。因为我的所有主键列和引用的键列都被索引了。 Messages 表中有近 50 万条记录。

【问题讨论】:

显示带有数据类型、索引和执行计划的表模式。 我已经更新了数据类型,我不能在这里共享表模式。所有整数字段都被索引。执行计划可以看这里ibb.co/pPFFJpZ 请说明查询的目的。并提供EXPLAIN SELECT ...。并提供SHOW CREATE TABLE(我们需要查看索引等)。 show index from tablename你能用详细的解释计划显示输出吗 @RickJames 查询的目标是获取最近的 40 封未读邮件。我将尝试解释一下,假设我们在联系人表中有 2 个电子邮件地址,email1@mydomain.com 和 email2@yourdomain.com。并且他们俩在 Messages 表中都有 10 条消息。现在假设 email2@yourdomain.com 在 DB 中有第二条消息处于未读状态,而 emial1 在 DB 中有第一条处于未读状态的消息,所以 email1 将显示在顶部。解释结果可以在ibb.co/FbPs3SD查看 【参考方案1】:

你提供的链接中的EXPLAIN好像不是你提供的SELECT,所以我不得不忽略它。

这个索引可能会有所帮助:

Messages:  (IsReceived, SubjectID, MessageID)

我添加了标签[groupwise-maximum]。它链接到许多其他正在做类似事情的问题。很少有人真正成功地优化了任务。我在这里比较了最快的技术:http://mysql.rjweb.org/doc.php/groupwise_max

【讨论】:

谢谢,添加建议的索引将查询执行时间从 12 秒减少到 5 秒以下.. 5 秒对于 UI 来说仍然很糟糕。查看我的链接和/或标签。 是的,你是对的,但仍然比 12 或 13 秒要好。我确实检查了链接,看来我必须对我的数据库架构进行一些小改动才能将其缩短到 2 到 3 秒。

以上是关于MySql - 添加 Order by 时查询缓慢的主要内容,如果未能解决你的问题,请参考以下文章

由于 ORDER BY 未使用索引,SQL 查询缓慢

使用 ORDER BY id 时 MySQL 查询慢

使用 order by 时,Mysql 查询运行非常慢

MySQL ORDER BY 根据日期时间查询返回不正确的结果

Mysql5.7中子查询时order by与group by合用无效的解决办法

Mysql查询(order by)很慢