PostgreSQL 条件连接的性能 - 查询优化
Posted
技术标签:
【中文标题】PostgreSQL 条件连接的性能 - 查询优化【英文标题】:Performance over PostgreSQL conditional join - Query optimization 【发布时间】:2021-03-12 01:35:42 【问题描述】:假设我有三个表,subscriptions
,其中有一个名为 type
的字段,它只能有 2 个值;
-
免费
高级版。
另外两个表称为premium_users
和free_users
。我想从subscriptions
表开始执行左连接,但问题是,根据type
字段的值,我只会在一个或另一个表中找到匹配的行,即如果@987654327 @ 等于'FREE',那么匹配的行将只在free_users
表中,反之亦然。
我正在考虑一些方法来做到这一点,例如 LEFT JOINING 两个表,然后使用 COALESCE 函数获取非空值,或者使用 UNION,两个不同的查询在两个查询上都使用 INNER JOIN,但是我我不太确定在性能方面哪种方法是最好的。此外,正如您猜想的那样,free_users
表几乎是premium_users
表的五倍。您应该知道的另一件事是,我通过user_id
字段加入,这是free_users
和premium_users
中的PK
所以,我的问题是:根据type
列的值将匹配到一个表或另一个表,这将是执行 JOIN 的最高效方式。如果不是两个表而是三个,甚至更多,这个解决方案会有什么不同吗?
免责声明:此数据库是 PostgreSQL,并且已经在生产环境中启动并运行,尽管我希望有一个 users
表,但短期内不会发生.
【问题讨论】:
您可以通过继承使用分区来创建统一用户表的外观,而无需停机或重组。 【参考方案1】:在性能方面什么是最好的?好吧,你应该试试你的数据和系统。
我的建议是两个左连接:
select s.*,
coalesce(fu.name, pu.name) as name
from subscriptions s left join
free_users fu
on fu.free_id = s.subscription_id and
s.type = 'free' left join
premium_users pu
on pu.premium_id = s.suscription_id and
s.type = 'premium';
您希望在 free_users(free_id)
和 premium_users(premium_id)
上建立索引。这些可能是“免费的”,因为这些 id 应该是表中的主键。
如果您使用union all
,那么优化器可能不会对连接使用索引。不使用索引可能会对性能产生可怕的影响。
【讨论】:
以上是关于PostgreSQL 条件连接的性能 - 查询优化的主要内容,如果未能解决你的问题,请参考以下文章