连接谓词顺序

Join predicate order

每当我在 Sql 控制台上被要求准备和 Join 查询时,我总是感到好笑和困惑(同时)。

大多数混淆的原因主要是基于以下事实 whether/or 而不是连接谓词的 顺序 在连接结果中具有任何重要性。

例子。

SELECT  "zones"."name", "ip_addresses".*
    FROM  "ip_addresses"
    INNER JOIN  "zones" ON "zones"."id" = "ip_addresses"."zone_id"
    WHERE  "ip_addresses"."resporg_accnt_id" = 1
      AND  "zones"."name" = 'us-central1'
    LIMIT  1; 

给定 sql 查询,连接谓词如下所示。

... INNER JOIN "zones" ON "zones"."id" = "ip_addresses"."zone_id" WHERE "ip_addresses"."resporg_accnt_id"

现在,它对 Join 的性能 以及获得的结果的真实性有什么影响吗?如果碰巧把谓词改成这样

... INNER JOIN "zones" ON "ip_addresses"."zone_id" = "zones"."id" WHERE "ip_addresses"."resporg_accnt_id"

谓词顺序不会对您的情况产生影响,这是一个简单的相等条件,但我个人喜欢将 table 中的列放在 JOIN 上每个 ON 条件的左轴

SELECT ...
  FROM ip_addresses ia

  JOIN zones z
    ON z.id = ia.zone_id 

 WHERE ...

优化器可以在 JOIN 期间使用这些列上可用的任何索引,我发现以这种方式更容易可视化。

任何其他条件也往往出现在 JOIN 的 table 列上,我再次发现当此 table 始终位于 LHS


不完全相同,但我确实看到了一个案例,其中性能受到要隔离的列的选择的影响

我认为 JOIN 看起来像

SELECT ...
  FROM table_a a

  JOIN table_b b
    ON a.id = b.id - 1

将其更改为

SELECT ...
  FROM table_a a

  JOIN table_b b
    ON b.id = a.id + 1

允许优化器在 b.id 上使用索引,但可能以 a.id

上的索引为代价

我怀疑这种查询可能需要根据具体情况进行分析


此外,我可能也会调换您的 table 订单并写下您的原始查询:

SELECT z.name,
       ia.* 
  FROM zones z 

  JOIN ip_addresses ia
    ON ia.zone_id = z.id
   AND ia.resporg_accnt_id = 1

 WHERE z.name = 'us-central1' 
 LIMIT 1

从概念上讲,你是说 "Start with the 'us-central1' zone and fetch me all the ip_addresses associated with a resporg_accnt_id of 1"

如果您想验证您的情况没有差异,请检查 EXPLAIN 计划