MariaDB group by 很慢

问题描述 投票:0回答:2

我有一个场景,我试图从超过 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 行?我是否以错误的方式处理这个问题?

感谢您一直以来的指导和支持

group-by mariadb query-optimization
2个回答
0
投票

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

0
投票

尝试这个复合索引。我相信它涵盖,您内心的疑问。

CREATE INDEX to_parent_id ON msg (msg_to, parent, msg_id);

内部查询应该可以通过对此索引进行范围扫描来实现。

© www.soinside.com 2019 - 2024. All rights reserved.