超亿级大表如何提取另一表存在对应MemberID的记录?原写法是否正确
原写法的问题
你最初的SQL写法存在逻辑错误:无关联条件的EXISTS子句只会判断table2是否为空,只要table2里有至少1条记录,判断结果就永远为真,最终会返回table1的全量数据,完全达不到筛选目标。
你必须将判断条件修改为带关联的版本,推荐进一步优化为select 1减少不必要的字段读取:
where exists (select 1 from table2 where table1.MemberID = table2.MemberID)
亿级大表的最优处理方案
你用的是SAS环境的proc sql,针对超大规模数据集,有以下优先级更高的优化方案,效果普遍优于普通JOIN写法:
- 优先建索引:给
table1和table2的MemberID字段都创建索引,关联时可以避免全表扫描,性能提升幅度可达数倍。如果table2是体量远小于table1的去重小表(百万级及以内MemberID),也可以直接用更简洁的IN写法,SAS优化器对小表IN子句的优化非常成熟:where MemberID in (select MemberID from table2) - 排序后用data步merge效率更高:如果没有提前建索引,优先将两张表按
MemberID排序后用data步合并,比SQL写法的性能高30%以上,更适合亿级数据集处理:/* table2本身已经去重,只需按MemberID排序 */ proc sort data=table2; by MemberID; run; proc sort data=table1; by MemberID; run; data tablewant; merge table1 (in=a) table2 (in=b keep=MemberID); by MemberID; if a and b; run; - 开启并行提升速度:硬件条件允许的情况下,提前开启SAS多线程选项,调用多核资源处理排序、合并操作:
options threads cpucount=你的CPU实际核心数;
关于JOIN的效果:如果两张表都已经对MemberID建了索引,关联条件正确的INNER JOIN和EXISTS的性能差异极小,SAS优化器会生成几乎一致的执行计划,不需要刻意切换。
内容的提问来源于stack exchange,提问作者haveylife
相关产品推荐
相关产品推荐

