我有一个场景,我试图从超过 200 万行中获取用户的最新消息,并按其父(或线程)ID 对它们进行分组。然而,这种分组导致查询时间在 1s 左右,比没有 group by 慢了大约 1000 倍。
这是桌子
CREATE TABLE `msg` (
`msg_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`msg_to` int(10) unsigned NOT NULL,
`msg_from` int(10) unsigned NOT NULL,
`msg` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL,
`date` timestamp NOT NULL DEFAULT current_timestamp(),
`parent` int(10) unsigned NOT NULL,
PRIMARY KEY (`msg_id`),
KEY `msg_toIX` (`msg_to`) USING BTREE,
KEY `msg_fromIX` (`msg_from`) USING BTREE,
KEY `parentIX` (`parent`) USING BTREE )
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
这是我的询问
SELECT a.msg_id, a.msg_from, a.msg FROM msg a
JOIN(SELECT MAX(msg_id) maxid FROM msg WHERE msg_to = 23 GROUP BY parent ORDER BY msg_id DESC LIMIT 10) b
ON a.msg_id IN (b.maxid)
ORDER BY a.msg_id DESC LIMIT 10
这是否已经达到了预期的效果,或者我应该获得更好的性能,因为我可以使用条件而不使用 group by 子句在 0.001 中提取 10,000 行?我是否以错误的方式处理这个问题?
感谢您一直以来的指导和支持
为
parent
和 msg_id
创建复合索引,以便优化获取每个父级的最大 ID。
CREATE TABLE `msg` (
`msg_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`msg_to` int(10) unsigned NOT NULL,
`msg_from` int(10) unsigned NOT NULL,
`msg` varchar(500) COLLATE utf8mb4_unicode_ci NOT NULL,
`date` timestamp NOT NULL DEFAULT current_timestamp(),
`parent` int(10) unsigned NOT NULL,
PRIMARY KEY (`msg_id`),
KEY `msg_toIX` (`msg_to`) USING BTREE,
KEY `msg_fromIX` (`msg_from`) USING BTREE,
KEY `parentIX` (`parent`, msg_id) USING BTREE )
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci