需要帮助来优化此查询
任务是从friends
表中选择我的朋友,检查他们中是否有任何一个都在忽略表中,从用户表中获取他们的信息,以及从消息表中获取最后一个消息日期。我的朋友也可以是团体的。
我的查询:
SELECT
`u`.`id`, `u`.`login`, `u`.`name`, `u`.`surname`,
CONCAT(`u`.`name`, ' ', `u`.`surname`) AS `namesurname`, `u`.`avatar`,
`u`.`status`, `u`.`status_text`, `u`.`last_active`, `u`.`type`,
`f`.`status` AS `friend_state`, `i`.`date` AS `ignore_date`,
MAX(`m`.`date`) AS `last_message_date`
FROM `friends` AS f
INNER JOIN `users` AS u ON `u`.`id`=`f`.`friend_id`
LEFT JOIN `ignore` AS `i` ON `i`.`uid`='10' AND `i`.`ignore_id`=`f`.`friend_id`
LEFT JOIN `messages` AS `m` ON `m`.`date`>DATE_ADD(NOW(), INTERVAL -1 DAY) AND
(
(`m`.`fromid`=`u`.`id` AND `m`.`toid`='10') OR
(`m`.`toid`=`u`.`id` AND `m`.`fromid`='10') OR
(`m`.`toid`=`u`.`id` AND `m`.`toid` IN (16,22,27))
)
WHERE `f`.`uid`='10'
GROUP BY `u`.`id`
ORDER BY `last_message_date` DESC, `namesurname`
对于170k条消息,此查询耗时2.2-2.5秒。
如果我删除
(`m`.`toid`=`u`.`id` AND `m`.`toid` IN (16,22,27))
花费了0.55秒
10-是我的用户ID
16,22,27-群组ID
我需要这一行(m
。toid
= u
。id
和m
。toid
IN(16,22,27 )),因为在群聊中,它不应该取决于发送最后一条消息的人。
预先感谢
答案 0 :(得分:0)
您可能不需要LEFT
。假设,我将ORs
变成UNIONs
并使用以下命令 start
由于您尚未提供SHOW CREATE TABLE
,因此我猜想messages
有PRIMARY KEY(mid)
。
SELECT ...
FROM ( ( SELECT mid FROM messages WHERE fromid = u.id AND toid = 10 )
UNION ALL
( SELECT mid FROM messages WHERE toid = u.id AND fromid = 10 )
UNION ALL
( SELECT mid FROM messages WHERE toid = u.id AND toid IN (16,22,27) ) AS um
JOIN users AS u ON ...
JOIN
糟糕,我将首先尝试在messages
中尝试做尽可能多的事情,假设1天的限制是一个重要的过滤条件。 (请注意,估计需要扫描17万行。)
首先检查一下它是否“快速”,并且不传递“太多”的行:
SELECT COUNT(*) FROM (
( SELECT toid AS either_id, MAX(date) AS last_date FROM messages
WHERE toid IN (10, 16,22,27) AND date > NOW() + INTERVAL 1 DAY )
UNION ALL -- or, if you get dups, UNION ALL
( SELECT fromid, MAX(date) FROM messages
WHERE fromid = 10 AND date > NOW() + INTERVAL 1 DAY )
) um;
假设没问题,然后继续工作
SELECT ...
FROM ( ... ) AS um -- the derived table above
JOIN users AS u ON um.either_id = u.id
JOIN ... -- the rest of the stuff
索引...
messages: (toid, date)
messages: (fromid, date)
(这是一个非常混乱的查询,因此我对自己的帮助没有信心。)