提问人:Luke Hutchison 提问时间:11/15/2023 更新时间:11/15/2023 访问量:29
PostgreSQL 是否足够智能,可以避免为每一行重新运行常量连接表达式?
Is PostgreSQL smart enough to avoid re-running constant join expressions for each row?
问:
如果联接或子选择不依赖于行中的任何其他内容,Postgres 是否足够智能,不会为每个结果行重新运行联接或子选择?
例如:
在 Postgres 中,我有两个表,并且 .我想编写一个查询,返回所有处于活动状态的用户的配置文件,并且仅当调用用户(其在变量中提供)也处于活动状态时才应返回这些配置文件。在 SQL 中,这将是:account
profile
user_id
$userId
select * from profile
left outer join account as viewer_account on
viewer_account.user_id = $userId
left outer join account as profile_account on
profile_account.user_id = profile.user_id
where
viewer_account.account_status = 'active' and
profile_account.account_status = 'active'
我的问题是,每一行都是一样的——它不依赖于结果(具体来说,它不依赖于 ,就像 一样)。但是,是针对每一行执行第一个外部连接(浪费工作),还是只执行一次,然后复制到结果集的每一行中?viewer_account
profile
profile.user_id
profile_account
答:
2赞
Maimoona Abid
11/15/2023
#1
通常,PostgreSQL 查询规划器足够智能,可以识别以下场景:对于完整结果集,查询的一部分可能只计算一次,并且不依赖于正在处理的行。通过仅计算一次初始联接的结果并重用它,它可能会适当地优化执行计划。检查计划器选择的特定执行计划的 EXPLAIN 输出。
EXPLAIN SELECT * FROM profile
LEFT OUTER JOIN account AS viewer_account ON viewer_account.user_id = $userId
LEFT OUTER JOIN account AS profile_account ON profile_account.user_id = profile.user_id
WHERE viewer_account.account_status = 'active' AND profile_account.account_status = 'active';
希望对您有所帮助:)
评论
0赞
Luke Hutchison
11/15/2023
谢谢!看起来索引扫描是从 和 之间的哈希连接中取出的,并作为单独的操作运行,所以是的,这看起来它会以最佳方式工作。viewer_account
profile_account
profile
评论
explain(analyze, verbose, buffers)