【问题标题】:Performance: LEFT JOIN vs SUBQUERY性能:LEFT JOIN vs SUBQUERY
【发布时间】:2015-10-22 06:55:37
【问题描述】:

我使用的是 PostgreSQL 9.3 并有以下表格(简化为仅显示相关字段):

SITES:
id
name
...

DEVICES:
id
site_id
mac_address UNIQUE
...

给定特定设备的mac_address,我想获取关联site 的详细信息。我有以下两个查询:

使用左连接:

SELECT s.* FROM sites s
LEFT JOIN devices d ON s.id = d.site_id
WHERE d.mac_address = '00:00:00:00:00:00';

使用子查询:

SELECT s.* FROM sites s
WHERE s.id IN (SELECT d.site_id FROM devices d WHERE d.mac_address = '00:00:00:00:00:00');

对于无限增长的数据库,这两个查询中哪一个的性能最好?我一直倾向于LEFT JOIN 选项,但我很想知道这两种速率在大型数据集上的表现如何。

【问题讨论】:

  • EXPLAIN自己查吧。
  • 或者更好:使用explain analyze。另外:如果devices 中有多行具有相同的 mac_address,那么这两个语句的作用不同。
  • 我认为它们甚至会生成不同的结果集,因此它们是无与伦比的。
  • @Caramiriel 我相信他们返回“相同”的结果集。
  • 伙计们,我们在浪费彼此的时间 - 解决方案是在前两个 cmets 中提供的。我们停止这个聊天怎么样 OP 去检查EXPLAIN ;-)

标签: performance postgresql optimization subquery left-join


【解决方案1】:

它通常不会有任何区别,因为它们应该产生相同的查询计划。至少,EXISTS 子查询会; IN 并不像往常一样经过智能优化。

对于子查询,您通常应该首选EXISTS (...),而不是使用IN (...)

SELECT s.*
FROM sites s
WHERE EXISTS (
  SELECT 1
  FROM devices d
  WHERE d.mac_address = '00:00:00:00:00:00'
    AND d.site_id = s.id
);

【讨论】:

  • 由于mac_address 是独一无二的,我不认为INEXISTS 会有很大的不同。
  • 我以前从未使用过EXISTS,看起来它在这种情况下可能有用。从文档中:“子查询通常只会执行到足以确定是否至少返回一行,而不是一直到完成”。告诉我EXISTS 将在mac_address 匹配后停止,而IN 将继续运行。可以对数十万行产生影响。
猜你喜欢
  • 2011-10-30
  • 2011-11-13
  • 2013-11-02
  • 1970-01-01
  • 2015-09-21
  • 2016-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多