大数量级下拼接主键表与联合主键表最优关联方案咨询
最优关联方式结论
四种可选写法中,性能最优的是第二种:
on Table1.CustomerId = Table2.CustomerId and Table1.SnapshotDate = Table2.SnapshotDate
各写法性能对比分析
- 第一种写法:
on Table1.CustomerPk = Table2.CustomerId || to_number(TO_CHAR(Table2.SnapshotDate,'YYYYMMDDHH24MISS'))
关联时需要对Table2的两个字段实时做函数计算、拼接生成匹配值,无法用上Table2的联合主键索引,额外计算开销大,大数据量下性能极低,不推荐使用。 - 第三种写法:
on Table1.CustomerId = Table2.CustomerId where Table1.SnapshotDate = Table2.SnapshotDate
如果是内关联,执行计划大概率会被优化器适配为和第二种写法等价,但如果是左/右/全外关联,where条件会过滤掉不满足日期匹配的行,直接改变外关联的语义,且写法不符合关联条件统一放在on子句的规范,不如第二种写法通用、稳定。 - 第四种写法:
on left(Table1.CustomerPk, 12) = Table2.CustomerId and right(Table1.SnapshotDate, 19) = Table2.SnapshotDate
关联时需要对Table1的两个字段做字符串截取计算,完全无法用上Table1的主键索引和原生字段索引,会触发全表扫描,是四种写法中性能最差的,完全不推荐。 - 第二种写法优势:两个关联条件均为直接匹配两表原生存储的独立字段,刚好可以命中Table2的双字段联合主键索引,也可以用上Table1的
(CustomerId, SnapshotDate)联合索引(如有),无额外函数计算开销,优化器可以生成最高效的执行计划,关联效率远高于其余三种写法。
额外性能优化建议
- 索引补充:如果Table1还未创建
(CustomerId, SnapshotDate)联合索引,尽快补充创建,完全匹配关联条件,避免全表扫描Table1。 - 谓词下推:如果查询有指定快照日期范围、客户范围等过滤条件,先通过子查询/CTE把两个表的待关联数据集缩小后再做关联,不要全表关联后再过滤。
- 冗余字段优化:如果这类关联是高频查询,可以提前在Table2中冗余存储计算好的
CustomerPk字段并建索引,关联时直接匹配两表的单字段主键,性能可以进一步提升。 - 类型对齐:关联前确认两表
CustomerId、SnapshotDate字段的数据类型完全一致,避免隐式类型转换导致索引失效。
内容的提问来源于stack exchange,提问作者Kellerness
相关产品推荐
相关产品推荐

