8

一般来说,使用 JOIN 选择行与 EXISTS where 子句之间是否存在性能差异?搜索各种问答网站表明加入更有效,但我记得很久以前就知道 EXISTS 在 Teradata 中更好。

我确实看到了其他 SO 答案,例如thisthis,但我的问题是针对 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 所述)。

我的例子可能太微不足道了,看不出有什么区别;我只是在寻找编码指导。

4

1 回答 1

7

NOT EXISTS 比使用 LEFT OUTER JOIN 更有效地排除使用 IS NULL 条件从参与表中丢失的记录,因为优化器将选择使用带有 NOT EXISTS 谓词的 EXCLUSION MERGE JOIN。

虽然您的第二次测试没有为您使用的数据集产生令人印象深刻的结果,但随着数据量的增加,从 NOT EXISTS over LEFT JOIN 的性能提升非常明显。请记住,表需要由参与 NOT EXISTS 连接的列进行散列分布,就像它们在 LEFT JOIN 中一样。因此,数据倾斜会影响 EXCLUSION MERGE JOIN 的性能。

编辑:

Typically, I would defer to EXISTS as a replacement for IN instead of using it for re-writing a join solution. This is especially true when the column(s) participating in the logical comparison can be NULL. That's not to say you couldn't use EXISTS in place of an INNER JOIN. Instead of an EXCLUSION JOIN you will end up with an INCLUSION JOIN. The INNER JOIN is in essence an inclusion join to begin with. I'm sure there are some nuances that I am overlooking but you can find those in the manuals if you wish to take the time to read them.

于 2012-12-04T18:35:42.573 回答