连接谓词顺序
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
计划
每当我在 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
计划