mysql多表联合查询,加条件筛选,需要排序分页,要求不使用join连接,要如何实现?

发布于 2022-09-06 11:07:48 字数 1479 浏览 18 评论 0

问题背景:

  • 有a、b、c三个表,a跟b、c都是一对多的关系,a有自增主键a.id,这是排序分页的依据,但按BOSS要求,不许在b、c表中添加a.id的冗余字段(包括外键手段,外键是使用的a中另一个保证唯一的定长字符串a.guid);
  • b、c表中均有字段用于作筛选条件,且由于a跟b、c都是一对多的关系,无法在a表中添加b、c表的筛选用字段作冗余;
  • 说是由于预计数据量会非常大(百万级),不允许使用join连接,且由于考虑以后迁移其他数据库的可能性,不允许使用自增主键id做外键,包括不允许使用自增主键id作为其他表的冗余字段。

需求:

  • 获取a表数据列表,分页显示,排序依据是a.id;
  • 有必选的筛选条件,在a表中,在此举例为a.set;
  • 有可选的筛选条件,条件分别在b、c表中,在此举例为b.type,c.name。

探索(此问题未解决,求助各位大佬帮忙):

  • 此问题的等价join连接SQL语句如下所示:

    SELECT a.id,a.guid,a.col1,a.col2 
    FROM a 
        INNER JOIN b ON a.guid = b.a_guid
        INNER JOIN c ON a.guid = c.a_guid
    WHERE a.set = 'xxx'          -- 必选条件
        AND b.type = 1           -- 整数,可选筛选条件
        AND c.name LIKE '%XXX%'  -- 模糊查询,可选筛选条件
    GROUP BY a.guid              -- 去重
    ORDER BY a.id                -- 按a.id排序
    LIMIT 0,10                   -- 分页
    ;
  • 不允许使用join连接,故思路自然是添加冗余字段,问题背景也说明了a表无法添加b、c表的冗余字段,故在b、c表中都添加了a_set(即a.set)的冗余字段;
  • 若不考虑分页,仅根据单独的可选筛选条件自然可以先筛选出a.guid,如根据b.type筛选:

    SELECT b.a_guid FROM b WHERE b.a_set = 'xxx' AND b.type = 1 GROUP BY b.a_guid;
  • 但这样问题自然在于b表中没有a.id字段可供排序,无法进行分页,分页思路自然是上面的语句查询出b.a_guid的结果集后,在a表中使用IN进行查询,然后按a.id进行排序分页,但此思路又有个问题是本身a、b、c三表的数据量预计就会很大,筛选出的b.a_guid的结果集可能也会非常大,可能会导致SQL语句超出长度限制,即便增加了SQL语句的长度限制或者使用子查询的方法,但IN中的数据量太多的话,不也是会很影响查询效率吗,会不会效率还不如使用JOIN连接?
  • 就此,思路卡在此处,实在想不出好的解决方案,在此求助路过的大神帮忙,提供一下解决的思路

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凉城凉梦凉人心 2022-09-13 11:07:48

不想有冗余字段,那就建个关联表,把a b 表的数据关联起来,想排序就加个a.id,索引建起来。

最好不要用IN,In的效率比较低。很多时候JOIN的效率反而更高的,你用到JOIN了已经涉及到多表了,关系型数据库,干的就是关系,擅长的就是查询;百万级,其实ok的;就是控制一下join的表数,关联越多效率就越低。

根据你的业务来设计数据库,业务体现数据未来可能的增长方向。可以先批量撸数据进去然后测一下sql效率看看。

格子衫的從容 2022-09-13 11:07:48

解决了吗?老哥

我在工作中也遇到了类似的问题,不过公司没限制使用join,但是我平时自己做项目习惯在代码中手动关联;然而这个情况 我也没想到有啥好办法解决

希望老哥分享下

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文