2

我正在尝试构建一个页面,其中显示成员收到的消息列表。我想出了这个 mySQL 查询,但它运行得非常慢。执行它至少需要 10 秒。

SELECT senderid,
       receiverid
FROM   messages
WHERE  ( receiverid, sentdate ) IN (SELECT receiverid,
                                           Max(sentdate)
                                    FROM   messages
                                    WHERE  receiverid = '1'
                                    GROUP  BY senderid)
ORDER  BY sentdate DESC 

这是我正在使用的数据库:

`autoID` mediumint(11) 无符号 NOT NULL AUTO_INCREMENT
`senderID` mediumint(11) 无符号 DEFAULT '0'
`receiverID` mediumint(11) unsigned DEFAULT '0'
`sentDate` 日期时间默认 '0000-00-00 00:00:00'
`消息`长文本
主键(`autoID`)
KEY `receiverID` (`receiverID`)
KEY `senderID` (`senderID`)

该数据库只有 150,000 个条目。我正在运行我自己的专用服务器,上面只有那个 mySQL 数据库。

任何帮助是极大的赞赏。

G-Nugget,我在 sentDate 上添加了一个索引,但速度没有增加。这是解释(对不起,显示的方式。不知道我还能怎么做):

id:1
select_type:PRIMARY
table:messages
type:ALL
possible_keys:null
keys:null
key_len:null
ref:null
rows:149433
Extra:Using where; 使用文件排序

id:2
select_type:DEPENDENT SUBQUERY
table:messages
type:ref
possible_keys:receiverID
key:receiverID
key_len:4
ref:const
rows:20
Extra:Using where; 使用临时的;使用文件排序

4

2 回答 2

1

这个查询如何产生你提到的结果集?

SELECT m.senderid,
       m.receiverid
  FROM messages m
  JOIN (
            SELECT  max(autoID) autoID, 
                    receiverID, SenderID
              FROM  messages
          GROUP BY  receiverId, SenderID
       ) X on m.autoID = x.AutoId
  WHERE m.receiverId = '1'
  ORDER BY m.autoID desc

这利用了 autoID 和 sentdate 很可能都随着时间的推移单调增加的假设。它在每对不同的发送者/接收者之间提取最新消息的 ID,然后使用这些 ID 选择要显示的消息表的子集。

于 2012-11-27T02:14:14.937 回答
0

在 MySQL 中,子查询in没有正确优化。您的查询有点复杂。我认为这是编写查询的有效方法:

SELECT senderid,
       receiverid
FROM   messages m
WHERE  m.receiverid = '1' and
       exists (SELECT 1
               FROM   messages m1
               WHERE  m1.receiverid = '1'
               GROUP  BY m1.senderid
               having max(sentdate) =  m.sentdate)
ORDER  BY sentdate DESC 

您的查询似乎正在尝试从每次发送到“1”获取最新消息。一个更简单的版本可能是:

select senderid, receiverid
from messages m
where m.receiverid = '1'

也就是说,每个发件人 ID 都将包含在您的原始查询中,因为它们最近的发送日期将匹配in条件。您可以有两个日期和时间完全相同的发件人。是否需要显示此类重复项?

于 2012-11-27T02:43:56.070 回答