【问题标题】:Performance over PostgreSQL conditional join - Query optimizationPostgreSQL 条件连接的性能 - 查询优化
【发布时间】:2021-03-12 01:35:42
【问题描述】:

假设我有三个表,subscriptions,其中有一个名为 type 的字段,它只能有 2 个值;

  1. 免费
  2. 高级版。

另外两个表称为premium_usersfree_users。我想从subscriptions 表开始执行左连接,但问题是,根据type 字段的值,我只会在一个或另一个表中找到匹配的行,即如果@987654327 @ 等于'FREE',那么匹配的行将只在free_users 表中,反之亦然。 我正在考虑一些方法来做到这一点,例如 LEFT JOINING 两个表,然后使用 COALESCE 函数获取非空值,或者使用 UNION,两个不同的查询在两个查询上都使用 INNER JOIN,但是我我不太确定在性能方面哪种方法是最好的。此外,正如您猜想的那样,free_users 表几乎是premium_users 表的五倍。您应该知道的另一件事是,我通过user_id 字段加入,这是free_userspremium_users 中的PK

所以,我的问题是:根据type 列的值将匹配到一个表或另一个表,这将是执行 JOIN 的最高效方式。如果不是两个表而是三个,甚至更多,这个解决方案会有什么不同吗?

免责声明:此数据库是 PostgreSQL,并且已经在生产环境中启动并运行,尽管我希望有一个 users 表,但短期内不会发生.

【问题讨论】:

  • 您可以通过继承使用分区来创建统一用户表的外观,而无需停机或重组。

标签: sql postgresql query-optimization


【解决方案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,那么优化器可能不会对连接使用索引。不使用索引可能会对性能产生可怕的影响。

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 2018-12-15
    相关资源
    最近更新 更多