如何高效实现基于name内连接+dt左连接的SQL表关联?
优化关联子查询的高效SQL实现方案
你的需求本质是保留t1的所有行,匹配t2中与当前t1行name相同且dt相同的记录,原关联子查询属于逐行执行的相关子查询,会重复扫描t2表,导致执行效率极低。
最优实现:直接使用多条件左连接
将原查询替换为以下SQL,语义完全等价,但执行效率会大幅提升:
SELECT * FROM t1 LEFT JOIN t2 ON t1.name = t2.name AND t1.date = t2.date;
性能优化建议
为了进一步加速匹配过程,建议在t2表上创建联合索引:
CREATE INDEX idx_t2_name_date ON t2(name, date);
数据库可以利用该索引快速定位到与t1行匹配的t2记录,避免全表扫描。
结果验证
用你提供的测试数据执行上述SQL,会得到与原查询完全一致的结果:
| t1.name | t1.date | t1.value | t2.name | t2.date | t2.value |
|---|---|---|---|---|---|
| 1 | 10 | 100 | 1 | 10 | 100 |
| 2 | 10 | 200 | NULL | NULL | NULL |
| 3 | 30 | 300 | 3 | 30 | 300 |
| 4 | 40 | 400 | NULL | NULL | NULL |
补充说明
如果业务逻辑需要先限定t2仅包含t1中存在的name,再做dt左连接,也可以用预过滤的写法,但这种场景下和多条件左连接结果一致,且性能差异不大:
SELECT t1.*, t2_filtered.* FROM t1 LEFT JOIN ( SELECT * FROM t2 WHERE name IN (SELECT DISTINCT name FROM t1) ) t2_filtered ON t1.name = t2_filtered.name AND t1.date = t2_filtered.date;
不过直接使用多条件左连接更简洁高效,优先推荐。
内容的提问来源于stack exchange,提问作者Tom Bennett
相关产品推荐
相关产品推荐

