【问题标题】:Nested SELECT vs JOIN performance嵌套 SELECT 与 JOIN 性能
【发布时间】:2022-06-10 19:55:13
【问题描述】:

我在 PostgreSQL 数据库中有以下两个表(为了示例而简化):

article

id summary
1 Article 1
2 Article 2
3 Article 3
... ...

event

id article_id eventtype_id comment
108 1 4 Comment 1
109 2 8 Comment 2
110 3 4 Comment 3
... ...

我只想为每个article 选择 1 个eventeventtype_id=4。结果应如下所示:

article_id article_summary event_comment
1 Article 1 Comment 1
2 Article 2
3 Article 3 Comment 3
...

这两个查询(Query 1Query 2)哪个运行得更快?它们返回相同的结果吗?

Query1:

SELECT
    a.id AS article_id,
    a.summary AS article_summary,
    evnt.comment AS event_comment
FROM 
    article a
LEFT JOIN
    event evnt ON evnt.article_id = a.id AND evnt.eventtype_id = 4;

Query2:

SELECT
    a.id AS article_id,
    a.summary AS article_summary,
    (
        SELECT
            evnt.comment
        FROM
            event evnt
        WHERE
            evnt.article_id = a.id AND
            evnt.eventtype_id = 4
        LIMIT 1
    ) AS event_comment
FROM 
    article a;

【问题讨论】:

  • 使用explain (analyze, buffers) - 它会告诉你哪一个跑得更快。 ericlippert.com/2012/12/17/performance-rant
  • Query2 在维护方面也是一个 PITA。您确定您(未来)团队中的每个人都能在半秒内阅读并理解这一点吗?如果没有,那就是您的代码出现新错误的时候。 LEFT JOIN 非常简单,很难错过。也不清楚为什么你有这个问题,你是唯一可以测量时间差异的人。我们没有您的数据。
  • 我发现这两个查询甚至没有返回相同的结果。如果Query 1eventtype_id = 4 关联的event 超过1 个,则Query 1 会为同一article 生成多行。 Query 2 只为每个 article 生成 1 行,即使它与 eventtype_id = 4 关联的 event 有多个。

标签: sql postgresql query-optimization


【解决方案1】:

除了查询不一样,正如你在cmets中所说的那样,一般来说,从性能角度来看,相关查询不被认为是合适的。这是因为这些查询是逐行应用的。它们通常在某些特定情况下很有帮助:read this。但是,即使在这些情况下,如果可能的话,最好在 exists 子句中使用它们,这样无论何时找到查询的行,它都会返回 true。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 2011-05-17
    • 2016-12-01
    • 2012-10-09
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    相关资源
    最近更新 更多