PostgreSQL 是否足够智能,可以避免为每一行重新运行常量连接表达式?

Is PostgreSQL smart enough to avoid re-running constant join expressions for each row?

提问人:Luke Hutchison 提问时间:11/15/2023 更新时间:11/15/2023 访问量:29

问:

如果联接或子选择不依赖于行中的任何其他内容,Postgres 是否足够智能,不会为每个结果行重新运行联接或子选择?

例如:

在 Postgres 中,我有两个表,并且 .我想编写一个查询,返回所有处于活动状态的用户的配置文件,并且仅当调用用户(其在变量中提供)也处于活动状态时才应返回这些配置文件。在 SQL 中,这将是:accountprofileuser_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_accountprofileprofile.user_idprofile_account

SQL 数据库 PostgreSQL 查询优化

评论

1赞 jarlh 11/15/2023
我还希望 Postgresql 能够实现在这里执行定期的内部连接。
1赞 Richard Huxton 11/15/2023
你为什么要费心在互联网上随机询问人,而不是运行EXPLAIN ANALYZE并查看它的实际作用?
0赞 Luke Hutchison 11/15/2023
@RichardHuxton因为我是 Postgres 的新手,甚至不知道如何使用它(但我会去查一下)。请对 n00bs 有一点同情心吗?
0赞 Richard Huxton 11/15/2023
在这种情况下,不要担心性能调优的细节,而是专注于内部连接和外部连接之间的差异,就像@jarlh指出的那样。
1赞 Frank Heikens 11/15/2023
让数据库告诉你: postgresql.org/docs/current/using-explain.html 实际上,你的 SQL 语句总是需要类似的东西。只是解释几乎什么也没告诉你。explain(analyze, verbose, buffers)

答:

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_accountprofile_accountprofile