我有这个选择来获得聊天(像facebook收件箱)。它将显示最近的消息,按发送它们的用户分组。
SELECT c.id, c.from, c.to, c.sent, c.message, c.recd FROM chat c
WHERE c.id IN(
SELECT MAX(id) FROM chat
WHERE (`to` = 1 and `del_to_status` = '0') or (`from` = 1 and `del_from_status` = '0')
GROUP BY CASE WHEN 1 = `to` THEN `from` ELSE `to` END
)
ORDER BY id DESC
limit 60
问题是大约需要8秒钟。
`chat` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`from` int(11) UNSIGNED NOT NULL,
`to` int(11) UNSIGNED NOT NULL,
`message` text NOT NULL,
`sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`recd` tinyint(1) NOT NULL DEFAULT '0',
`del_from_status` tinyint(1) NOT NULL DEFAULT '0',
`del_to_status` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `from` (`from`),
KEY `to` (`to`),
FOREIGN KEY (`from`) REFERENCES cadastro (`id`),
FOREIGN KEY (`to`) REFERENCES cadastro (`id`)
)
有没有办法索引或重新编写这个选择,以获得更好的速度?
2条答案
按热度按时间bgibtngc1#
我假设是专栏
id
已经索引,因为它可能是表的主键。如果不是这样,请添加索引:然后,如果子查询的选择性很好,那么索引将有所帮助。选择性是行的百分比
select
与总行数进行比较。是50%,5%,0.5%吗?如果为5%或更低,则以下索引将有所帮助:请注意,列名不要使用保留字:我指的是from列。这只会让每个人的生活都很艰难。
5kgi1eie2#
我假设chat.id已被索引。如果没有,当然应该添加索引。
如果是索引的,mysql在子选择方面通常非常慢。
您可以做的一件事是将子选择转换为临时表并与之联接。
它看起来像
然后,只需连接temp表:
临时表只在会话期间有效,因此如果在phpmyadmin中测试,请记住用“;”同时执行这两个查询在他们之间。
如果你尝试这个分享你的结果。