一般来说,使用 JOIN 选择行与 EXISTS where 子句之间是否存在性能差异?搜索各种问答网站表明加入更有效,但我记得很久以前就知道 EXISTS 在 Teradata 中更好。
我确实看到了其他 SO 答案,例如this和this,但我的问题是针对 Teradata 的。
例如,考虑这两个返回相同结果的查询:
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
group by 1
order by 1
-和-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
两个表上的主索引(唯一)是“srv_accs_id”。MY_BASE_TABLE 相当大(2 亿行),而 MY_TARGET_TABLE 相对较小(200,000 行)。
EXPLAIN 计划有一个显着的区别:第一个说两个表是“通过 RowHash 匹配扫描”连接的,第二个说“通过所有行扫描”。两者都说这是“一个全 AMP 加入步骤”,并且估计的总时间是相同的(0.32 秒)。
两个查询执行相同(我使用的是 Teradata 13.10)。
一个类似的实验来查找不匹配项,将 LEFT OUTER JOIN 与相应的 IS NULL where 子句与 NOT EXISTS 子查询进行比较,确实显示了性能差异:
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
left outer join MY_TARGET_TABLE x
on x.srv_accs_id=svc.srv_accs_id
where x.srv_accs_id is null
group by 1
order by 1
-和-
select svc.ltv_scr, count(*) as freq
from MY_BASE_TABLE svc
where not exists(
select 1
from MY_TARGET_TABLE x
where x.srv_accs_id=svc.srv_accs_id)
group by 1
order by 1
第二个查询计划更快(2.21 对 2.14 秒,如 EXPLAIN 所述)。
我的例子可能太微不足道了,看不出有什么区别;我只是在寻找编码指导。