来自两个多对多表的MYSQL搜索查询优化

Posted

技术标签:

【中文标题】来自两个多对多表的MYSQL搜索查询优化【英文标题】:MYSQL search query optimization from two many-to-many tables 【发布时间】:2021-03-09 13:45:17 【问题描述】:

我有三张桌子。

    tbl_post 用于帖子表。 (post_idx, post_created, post_title, ...) tbl_mention 用于提及表。 (mention_idx、mention_name、mention_img、...) tbl_post_mention 用于两个表之间的唯一多对多关系。 (post_idx,mention_idx)

例如,

PostA 可以有 MentionA 和 MentionB。 PostB 可以有 MentionA 和 MentionC。 PostC 不能有 MentionC 和 MentionC。

tbl_post 大约有百万行,tbl_mention 不到一百行,tbl_post_mention 有几百万行。这三个表都大量加载了外键、唯一索引等。

我正在尝试进行两个单独的搜索查询。

    搜索具有所有给定提及 ID 的帖子 ID[AND 条件] 搜索具有任何给定提及 ID 的帖子 ID[OR 条件]

然后加入 tbl_posttbl_mention 以填充有意义的数据,对结果进行排序,并返回前 n 个。最后,我希望有一个n个帖子列表,其中包含我的服务在前端显示所需的所有数据。

以下是相应的更简单的查询

SELECT post_idx 
FROM 
    (SELECT post_idx, count(*) as c 
    FROM tbl_post_mention 
    WHERE mention_idx in (1,95) 
    GROUP BY post_idx) AS A
WHERE c >= 2;

这个查询的问题是它在连接和排序之前已经是低效的了。仅此过程就需要 0.2 秒。

SELECT DISTINCT post_idx
FROM tbl_post_mention 
WHERE mention_idx in (1,95);

这是一个简单的索引范围扫描,但是由于 IN 语句,一旦开始将查询与其他表连接起来,查询就会再次变得昂贵。

我尝试了更复杂和“聪明”的查询,并尝试索引不同的列集但无济于事。在这种情况下我可以使用特殊的语法吗?也许是一个聪明的把戏?分区?还是我在这里遗漏了一些基本概念... :(

发送帮助。

【问题讨论】:

根据mysql.rjweb.org/doc.php/…优化多对多模式 【参考方案1】:

你想要的查询是这样的:

SELECT post_idx 
  FROM tbl_post_mention 
 WHERE mention_idx in (1,95) 
 GROUP BY post_idx
HAVING COUNT(*) >= 2

HAVING 子句执行您的 post-GROUP BY 过滤。

对你有帮助的索引是这个。

CREATE INDEX mentionsdex ON tbl_post_mention (mention_idx, post_idx);

覆盖您的查询,允许通过mention_idx 进行快速查找,然后按post_idx 进行分组。

通常所谓的连接表有两列——比如你的tbl_post_mention——当它们有一对索引的列顺序相反时工作效率最高。

【讨论】:

以上是关于来自两个多对多表的MYSQL搜索查询优化的主要内容,如果未能解决你的问题,请参考以下文章

用于连接多对多表的 Linq 查询

针对标签上的多对多连接优化 MySQL 查询

MySQL 基础 -- 多表关系(一对一1对多(多对一)多对多)多表查询(内连接外连接自连接子查询(嵌套查询)联合查询 union)笛卡儿积

MySQL学习笔记-多表查询(上)

阶段3 1.Mybatis_09.Mybatis的多表操作_8 mybatis多对多操作-查询角色获取角色下所属用户信息

python flask(多对多表查询)