首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JOIN、UNION和ORDER BY、使用temporary、使用filesort的子查询

使用JOIN、UNION和ORDER BY、使用temporary、使用filesort的子查询
EN

Stack Overflow用户
提问于 2011-10-20 07:51:17
回答 1查看 1.2K关注 0票数 0

我正在使用mysql作为消息传递系统。我正在尝试编写一个查询,它将拉取发送给或接收自每个其他用户的最后一条消息,该用户已经与该用户通信。

下面是保存所有消息的表:

代码语言:javascript
复制
CREATE TABLE `privatemessages` (
  `id` int(11) NOT NULL auto_increment,
  `recipient` int(11) NOT NULL,
  `sender` int(11) NOT NULL,
  `time` int(11) NOT NULL,
  `readstatus` int(11) NOT NULL,
  `message` varchar(255) NOT NULL,
  `messagetype` int(11) NOT NULL,
  `rdeleted` int(11) NOT NULL,
  `sdeleted` int(11) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `recipient` (`recipient`),
  KEY `sender` (`sender`),
  KEY `read` (`readstatus`),
  KEY `time` (`time`),
  KEY `openmessagingpanel` (`recipient`,`readstatus`),
  KEY `openpmthreadrev` (`recipient`,`sender`),
  KEY `openpmthread` (`sender`,`recipient`)
) ENGINE=InnoDB AUTO_INCREMENT=27587533 DEFAULT CHARSET=latin1$$

以下是给我带来问题的查询:

代码语言:javascript
复制
select * from 
(
select users.username, users.onlinestatus,users.profileimageid, privatemessages.id, privatemessages.time, privatemessages.message from privatemessages 
JOIN users on privatemessages.recipient=users.id WHERE sender=19 
UNION ALL 
select users.username, users.onlinestatus,users.profileimageid, privatemessages.id, privatemessages.time, privatemessages.message from privatemessages 
JOIN users on privatemessages.sender=users.id WHERE recipient=19 
ORDER BY id DESC
)
as testResult GROUP by testResult.username ORDER By id DESC;

查询以正确的顺序返回我想要的数据,但是对于有大量消息的用户来说,它非常慢。

下面是explain语句:

代码语言:javascript
复制
+----+--------------+-----------------+--------+------------------------------------------------------------------+--------------------+---------+---------------------------------+------+---------------------------------+
| id | select_type  | table           | type   | possible_keys                                                    | key                | key_len | ref                             | rows | Extra                           |
+----+--------------+-----------------+--------+------------------------------------------------------------------+--------------------+---------+---------------------------------+------+---------------------------------+
|  1 | PRIMARY      | <derived2>      | ALL    | NULL                                                             | NULL               | NULL    | NULL                            | 4246 | Using temporary; Using filesort |
|  2 | DERIVED      | privatemessages | ref    | recipient,sender,openmessagingpanel,openpmthreadrev,openpmthread | sender             | 4       |                                 | 1076 |                                 |
|  2 | DERIVED      | users           | eq_ref | PRIMARY                                                          | PRIMARY            | 4       | chat2.privatemessages.recipient |    1 |                                 |
|  3 | UNION        | privatemessages | ref    | recipient,sender,openmessagingpanel,openpmthreadrev,openpmthread | openmessagingpanel | 4       |                                 | 6490 |                                 |
|  3 | UNION        | users           | eq_ref | PRIMARY                                                          | PRIMARY            | 4       | chat2.privatemessages.sender    |    1 |                                 |
| NULL | UNION RESULT | <union2,3>      | ALL    | NULL                                                             | NULL               | NULL    | NULL                            | NULL | Using filesort                  |
+----+--------------+-----------------+--------+------------------------------------------------------------------+--------------------+---------+---------------------------------+------+---------------------------------+
6 rows in set (0.08 sec)

有没有更好的查询方法?谢谢

EN

回答 1

Stack Overflow用户

发布于 2011-10-20 08:14:50

尝试此查询

代码语言:javascript
复制
SELECT users.username, users.onlinestatus, users.profileimageid, temp.id, temp.time, temp.message
  FROM users
 INNER JOIN (SELECT id, time, message, recipient FROM privatemessages WHERE sender=19) temp
    ON temp.recipient=users.id
 UNION 
SELECT users.username, users.onlinestatus,users.profileimageid, temp.id, temp.time, temp.message
  FROM users
 INNER JOIN (SELECT id, time, message, sender FROM privatemessages WHERE sender=19) temp
    ON temp.sender=users.id
 GROUP BY username ORDER BY id DESC
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7829612

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档