当前位置: 首页 > 面试题库 >

JOIN与EXISTS的表现

胡鸿志
2023-03-14
问题内容

一般来说,使用JOIN选择行与EXISTS
where子句之间在性能上有区别吗?通过搜索各种问答网站,可以发现联接效率更高,但是我记得很久以前就知道,EXISTS在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

第二个查询计划更快(如EXPLAIN所述,为2.21秒对2.14秒)。

我的例子可能太琐碎,看不到区别。我只是在寻找编码指南。


问题答案:

NOT ISISTS比使用LEFT OUTER JOIN使用IS NULL条件排除参与表中缺少的记录的效率更高,因为优化程序将选择使用带有NOT
EXISTS谓词的EXCLUSION MERGE JOIN。

虽然您的第二项测试未对数据集产生令人印象深刻的结果,但随着数据量的增加,使用不存在连接而不是通过左联接获得的性能提升非常明显。请记住,表将需要像参加LEFT
JOIN一样,由参加NOT EXISTS联接的列进行散列分布。因此,数据偏斜会影响EXCLUSION MERGE JOIN的性能。

编辑:

通常,我会将EXISTS替换为IN,而不是将其用于重新编写联接解决方案。当参与逻辑比较的列可以为NULL时,尤其如此。这并不是说您不能使用EXISTS代替INNER
JOIN。代替EXCLUSION JOIN,您将最终获得INCLUSION JOIN。本质上,INNER
JOIN是一个包含联接。我敢肯定有些细微之处我会忽略,但是如果您希望花些时间阅读它们,可以在手册中找到它们。



 类似资料:
  • 问题内容: 和之间有什么区别? 交叉加入: 内部联接: 哪一种更好,为什么我要使用其中一种呢? 问题答案: 交叉联接不会合并行,如果每个表中有100行且1对1匹配,您将得到10.000个结果,Innerjoin在相同情况下将仅返回100行。 这两个示例将返回相同的结果: 交叉联接 内部联接 使用最后一种方法

  • 问题内容: 以下两个查询是子查询。两者相同,都对我有效。但是问题是方法1的查询大约需要10秒才能执行,而方法2的查询不到1秒。 我能够将方法1的查询转换为方法2,但是我不了解查询中正在发生什么。我一直想自己弄清楚。我真的很想了解以下两个查询之间的区别是什么,以及如何获得性能提升?它背后的逻辑是什么? 我是这些高级技术的新手。我希望有人能在这里帮助我。考虑到我阅读的文档并没有给我任何提示。 方法1:

  • 问题内容: 在我看来,您可以使用NOT EXISTS,NOT IN或LEFT JOIN WHERE IS NULL在SQL查询中执行相同的操作。例如: 我不确定所有语法是否正确,但这是我所见过的常规技术。我为什么选择一个使用另一个?性能会有所不同吗?哪一个是最快/最有效的?(如果取决于实现,我什么时候会使用每个?) 问题答案: NOT IN与NOT EXISTS与LEFT JOIN / IS NU

  • 问题内容: 从MySQL中的多个表中选择时,以下两个查询均返回相同的结果集。 这些查询中的一个比另一个查询 更好 或更有效吗?根据我在一个小的数据集(每个表中约有2000行)的测试中,它们都在大约相同的执行时间上返回了相同的结果集。 查询1: 查询2: 问题答案: 它们是相同的,但是语法不同。因此,您不应该期望这两种语法之间的性能差异。但是,建议使用最后一种语法(ANS SQL-92语法),有关更

  • 描述 (Description) 如果指定的散列或数组键存在,则此函数返回true,无论相应的值如何,即使它是.sunf。 如果EXPR是一个子程序,那么如果子程序已被声明(但不一定是已定义),则exists将返回1,否则返回0。 如果LIST是多个参数,或者是具有多个值的数组,则直接执行该命令而不使用shell。 语法 (Syntax) 以下是此函数的简单语法 - exists EXPR 返回

  • EXISTS key 检查给定 key 是否存在。 可用版本: >= 1.0.0 时间复杂度: O(1) 返回值: 若 key 存在,返回 1 ,否则返回 0 。 redis> SET db "redis" OK redis> EXISTS db (integer) 1 redis> DEL db (integer) 1 redis> EXISTS db (integer) 0