数据库外键设计 DM3外联接优化 通俗详解

amuwap 发布于 12 小时前 4 次阅读


Sql当中的外联接要是写出色,那会使你减少被业务方责骂的情况,不要再在查不到数据时,就将责任推给数据库了。

左外联接不是万能药

众多开发人员于初次接触 SQL 之际,其首要反应便是“只要左边表数据予以全部保留,那就运用 LEFT JOIN”,此习惯身处于 2026 年的当下依旧颇为普遍,我于某电商公司在 2025 年双十一之后所举行的复盘会议上,目睹了一位同事所撰写的报表查询情况,其中左表乃是有着 10 亿条记录的用户点击日志,右表则为商品信息,他采用了 LEFT JOIN,然而结果查询运行了 40 分钟却仍旧未得出结果。

左外连接情况下,确实可以实现返回左表的全部记录,然而,这也就表明了这般状况,即要是左表规模很大,右表索引构建得不完善,或者关联字段类型并非一致,那么数据库就不得不去执行大量的、没有实际效果的扫描操作了。而且,阿里云数据库团队在2025年对外公布数据时表明,大约37%的慢查询状况是由于对LEFT JOIN进行了过度使用,从而致使全表扫描现象的出现。而正确的做法是,首先要去评估右表的匹配率,倘若匹配率超过了95%,采用INNER JOIN的话,效率会更高。

右外联接其实很少单独用

右向外联接跟左向外联接在逻辑方面呈现出完全的对称状态,仅仅是方向有所相反。我于实际的项目当中观察到了一个十分有趣的现象,过去三年内所经手的6家互联网公司,没有任何一个开发人员会在正式的代码里面直接去写RIGHT JOIN。并非是它发挥不了作用,而是因大家习惯将主表放置在左边。比如说要保留右表的所有记录,完全能够借助调整表之顺序的方式,运用LEFT JOIN达成同样的效果。

可是存在一个场景是例外的情况。我于字节跳动2024年所分享的某一个案例当中瞧见,他们的BI团队在开展处理Power Query数据合并这个操作的时候,会特意采用右外联接的方式去保留维度表的全部记录。鉴于维度表一般规模较小并且稳定,右外联接能够让往后的业务人员在查看代码时更加直观地理解哪一个是主表。这个并非是SQL层面的必须如此,而是基于可读性以及维护习惯所做出的选择。

完全外联接全靠手动拼

MySQL里没有原生支持完全外联接,这致使好多开发人员碰到需要两边全保留这种场景时,干脆在代码里写两个查询然后合并。携程在2025年公布过一组数据,他们的订单系统每天有超过2000次全外联接需求,全都是借助UNION两个方向的外联接达成的。这种做法没有错,然而容易忽视重复行。

利用LEFT JOIN UNION RIGHT JOIN来正确模拟FULL JOIN是可行的办法,然而必须保证两边都不存在重复关联键,不然的话UNION会消重。要是你有保留重复行 的需求,那就得采用UNION ALL。在2026年1月,我应一家物流公司要求进行代码评审时,察觉到他们在模拟全数据外部联接时,疏漏了添加UNION的消重逻辑,从而致使运费计算少统计了300多万运输费用。这并非SQL自身存在问题,而是人对于数据特征的理解不够到位所造成的。

外联接的方向藏在图形工具里

众多刚毕业的校招生并不清楚,在Power BI、Tableau、Access这些图形化工具之中,那些带有箭头或者菱形的连线,其本质实际上就是在对外部联接之方向加以定义,我于2025年前往上海大学讲公开课时曾经询问过现场授课的学生,在其中超过80%的人都曾经拖曳过这些连线呀,然而却并不知晓它翻译成SQL之后会呈现出什么样的模样呢。

在Access查询设计视图当中,双击表之间的连线,会弹出对话框,让你去选到底是“包括所有来自表A的记录”,还是“包括所有来自表B的记录”,这实际上就是在配置LEFT JOIN或者RIGHT JOIN。其生成的SQL里会出现对应的LEFT JOIN关键字。理解这种对应关系,能够让你在图形工具出现错误的时候,直接切换到SQL视图进行手动修复,而非删掉之后重新绘制。这套逻辑从1992年的SQL标准一直到如今,几乎没有发生过改变。

一个WHERE条件就能毁掉外联接

最具隐蔽性的外联接的坑在于条件放置位置错误了,不少开发人员惯于在WHERE里增添过滤条件,然而却并未察觉到这样做会将外联接直接转变为内联接。在2024年的时候,我于平安科技目睹了一场事故,运维人员想要查询所有服务器的CPU峰值,左表为服务器列表,右表是监控指标,运用LEFT JOIN之后在WHERE里添加了一个“指标时间=昨天”,结果是没有监控数据的服务器直接被过滤出去了,有17台被漏报了,到了第二天就被业务追着询问。

倘若你打算给右表增添条件,然而又不想致使左表记录有所遗失,其标准做法是把该条件书写于ON子句当中,而非WHERE里,此区别在SQL Server、Oracle、PostgreSQL里呈现出一致的状况。当MySQL优化器在处置这般查询之际,会开展外连接消除优化,你觉得自己写了LEFT JOIN,可实际执行计划却是INNER JOIN。这并非数据库存在bug,而是教科书级别的经典错误。

学术界早把路铺好了

并非是直至今日外联接的优化问题方才出现,早在2001年被称作全国第十六届数据库学术会议举行其间,学者冯玉才以及黄琳倩等人于论文当中详细地对DM3数据库里的外联接查询优化规划进行了阐释、说明,此篇论文提出了以代价作为依据的联接顺序重新排列、外联接解除等算法策略,历经二十多年的时间过去现今国产的达梦、OceanBase、TiDB这类数据库在处理外联接之时,于底层原理方面依旧能够见到这些现有研究成果所遗留的痕迹。

能让你在面对“为什么这个查询这么慢”时,不仅只会加索引,还会从业务源头做减法的是你已理解了在2025年华为高斯数据库团队发表的技术白皮书当中的专门有一章讲外联接在分布式环境下的并行执行策略的相关研究背景,他们在其中提到,在跨分片数据关联时,那种情况下完全外联接的代价是极高的,为此建议业务在设计数据分布时就尽可能去避免,而这并非是技术存在没做到的情况,却是成本方面并不划算。

你可曾有过,因外联接写错致使数据对不上,进而被业务方追着使劲骂,一直骂到半夜的那般经历?欢迎于评论区去分享你那翻车得案例,点赞数过1000的话,我就紧接着去写SQL里头子查询那些极其要命的坑。