Postgresql 在Postgres中将三个表连接在一起的更有效的方法

Postgresql 在Postgres中将三个表连接在一起的更有效的方法,postgresql,join,processing-efficiency,Postgresql,Join,Processing Efficiency,我正在尝试将postgres中的三个表链接在一起 所有三个表都是从子查询生成的。第一个表通过变量call_sign作为完全联接链接到第二个表(因为我需要两个表的条目超集)。第三个表与第二个表之间有一个内部连接,该连接也处于调用状态(但理论上可以链接到第一个表) 查询运行得很慢,但我觉得随着添加更多数据,查询速度会变得更慢。我意识到我可以做一些事情来加快速度,比如不在子查询中提取不必要的数据,不在运行时将文本转换为数字。但是有没有更好的方法来构造这三个表之间的连接呢? 任何建议都将不胜感激,因

我正在尝试将postgres中的三个表链接在一起

所有三个表都是从子查询生成的。第一个表通过变量call_sign作为完全联接链接到第二个表(因为我需要两个表的条目超集)。第三个表与第二个表之间有一个内部连接,该连接也处于调用状态(但理论上可以链接到第一个表)

查询运行得很慢,但我觉得随着添加更多数据,查询速度会变得更慢。我意识到我可以做一些事情来加快速度,比如不在子查询中提取不必要的数据,不在运行时将文本转换为数字。但是有没有更好的方法来构造这三个表之间的连接呢?

任何建议都将不胜感激,因为我是博士后的新手

下面是代码:


如果可以的话,您将希望释放这些查询并在一个连接中完成所有操作。例如:

select <whatever you need>
from combo_fr f
JOIN combo_en e ON f.call_sign=e.call_sign
JOIN market_mf mf mf ON mf.call_sign=e.call_sign
JOIN combo_mk mk ON mk.call_sign=en.call_sign
选择
来自combo_fr f
在f.call\u sign=e.call\u sign上加入combo\u en e
在mf上加入市场。call\u sign=e.call\u sign
在mk.call\u sign=en.call\u sign上加入combo\u mk

我无法完全了解您在做什么,但为了处理呼号出现或不出现的位置,一些连接子句可能必须变成左连接。

在为所有四个相关表创建索引后,请尝试以下操作:

WITH nodup AS (
  SELECT call_sign FROM market_mf 
  EXCEPT SELECT call_sign FROM combo_fr
) SELECT     
      CAST(REPLACE(u.master_frequency_string, ',','.') AS DECIMAL) 
              AS master_frequency,
      u.call_sign AS master_call_sign,
      u.entity_type AS master_entity_type,
      u.licensee_id AS master_licensee_id,
      u.entity_name AS master_entity_name,
      combo_mk.market_name
    FROM (SELECT frequency_assigned AS master_frequency_string, call_sign, 
                 entity_type, licensee_id, entity_name
            FROM combo_fr
          UNION ALL SELECT lower_frequency, call_sign, 
                 entity_type, licensee_id, entity_name
            FROM market_mf INNER JOIN nodup USING (call_sign)
      ) AS u
    INNER JOIN combo_en USING (call_sign)
    INNER JOIN combo_mk USING (call_sign)
    ORDER BY 1 DESC;
我发布这篇文章是因为这是了解你需要什么的最简单的方法

  • 如果没有出现在
    market\u mf
    和中的
    call\u sign
    combo\u fr
    带节点…
    内部连接节点…
    可以省略
  • 我假设,
    call\u sign
    combo\u fr
    market\u mf
    两个表中都是唯一的(=每个表中没有两条记录具有相同的值),即使两个表中都可能出现值
  • 非常不幸的是,您是按计算列排序的,而计算是如此愚蠢。某种优化是一次性地将频率字符串转换为表本身中的所有频率字符串。这些步骤将是: (1) 向表中添加数字频率列(2)使用从当前文本列转换的值填充它们(3)通过输入具有所需小数分隔符的区域设置,将新值直接转换为新列

首先,当…为NULL时,您可以使用而不是
CASE
。其次,您应该删除subselect中的所有
ORDER BY
,这在这种情况下是完全无用的。在涉及的任何表中,
call\u sign
可以为NULL还是唯一?其他字段是否可以为空?换句话说,当…返回来自同一个表的每一行的值时,
是否会出现这种情况,或者答案中的某一行是来自
组合fr
市场mf
(忽略
呼叫符号
)的值的混合?谢谢@kennytm。COALESCE似乎只提高了很少的性能,但代码仍然更好看。同样感谢@Dario。删除子查询中的ORDER BY将性能提高了13%。Call\u符号永远不会为null,但可能是Call\u符号存在于第一个表(combo\u fr)或第二个表(market\u mf)中,我想同时提取这两个表。这有帮助吗?@Dario……创建随叫随到的索引标志确实改善了情况。多谢。我还将执行您建议的最后一步,并在一个新列中转换那些应该numeric@user3003374这是否意味着使用
联合
和两个后续的
内部联接
的方法不正确或正确,但比原来的方法更糟糕?
WITH nodup AS (
  SELECT call_sign FROM market_mf 
  EXCEPT SELECT call_sign FROM combo_fr
) SELECT     
      CAST(REPLACE(u.master_frequency_string, ',','.') AS DECIMAL) 
              AS master_frequency,
      u.call_sign AS master_call_sign,
      u.entity_type AS master_entity_type,
      u.licensee_id AS master_licensee_id,
      u.entity_name AS master_entity_name,
      combo_mk.market_name
    FROM (SELECT frequency_assigned AS master_frequency_string, call_sign, 
                 entity_type, licensee_id, entity_name
            FROM combo_fr
          UNION ALL SELECT lower_frequency, call_sign, 
                 entity_type, licensee_id, entity_name
            FROM market_mf INNER JOIN nodup USING (call_sign)
      ) AS u
    INNER JOIN combo_en USING (call_sign)
    INNER JOIN combo_mk USING (call_sign)
    ORDER BY 1 DESC;