【发布时间】:2017-04-14 12:14:21
【问题描述】:
我试图在 postgres 中将三个表链接在一起。
所有三个表都是从子查询生成的。第一个表通过变量 call_sign 作为 FULL JOIN 链接到第二个表(因为我想要两个表中条目的超集)。第三个表有一个 INNER JOIN,第二个表也在 call_sign 上(但理论上可以链接到第一个表)
查询运行但很慢,我觉得随着我添加更多数据会变得更慢。我意识到我可以做一些事情来加快速度——比如不要在子查询中提取不必要的数据,也不要即时将文本转换为数字。但是有没有更好的方法来构建这三个表之间的 JOIN?
任何建议都将不胜感激,因为我是 postgres 的新手。
代码如下:
select
(CASE
WHEN tmp1.frequency_assigned is NULL
THEN tmp2.lower_frequency
ELSE tmp1.frequency_assigned END) as master_frequency,
(CASE
WHEN tmp1.call_sign is NULL
THEN tmp2.call_sign
ELSE tmp1.call_sign END) as master_call_sign,
(CASE
WHEN tmp1.entity_type is NULL
THEN tmp2.entity_type
ELSE tmp1.entity_type END) as master_entity_type,
(CASE
WHEN tmp1.licensee_id is NULL
THEN tmp2.licensee_id
ELSE tmp1.licensee_id END) as master_licensee_id,
(CASE
WHEN tmp1.entity_name is NULL
THEN tmp2.entity_name
ELSE tmp1.entity_name END) as master_entity_name,
tmp3.market_name
FROM
(select cast(replace(frequency_assigned, ',','.') as decimal) AS frequency_assigned,
frequency_upper_band,
f.uls_file_number,
f.call_sign,
entity_type,
licensee_id,
entity_name
from combo_fr f INNER JOIN combo_en e
ON f.call_sign=e.call_sign
ORDER BY frequency_assigned DESC) tmp1
FULL JOIN
(select cast(replace(lower_frequency, ',','.') as decimal) AS lower_frequency,
upper_frequency,
e.uls_file_number,
mf.call_sign,
entity_type,
licensee_id,
entity_name
FROM market_mf mf INNER JOIN combo_en e
ON mf.call_sign=e.call_sign
ORDER BY lower_frequency DESC) tmp2
ON tmp1.call_sign=tmp2.call_sign
INNER JOIN
(select en.call_sign,
mk.market_name
FROM combo_mk mk
INNER JOIN combo_en en
ON mk.call_sign=en.call_sign) tmp3
ON tmp2.call_sign=tmp3.call_sign
ORDER BY master_frequency DESC;
【问题讨论】:
-
首先你可以用
COALESCE代替CASE WHEN … IS NULL。 -
其次,你应该删除所有子选择中的
ORDER BY,在这种情况下完全没用。 -
call_sign在所涉及的任何表中是否可以为空或唯一?其他字段可以为空吗?换句话说,那些CASE WHEN...是否会返回来自同一个表的每一行的值,或者答案中的某些行是来自combo_fr和market_mf的值的混合(忽略@987654330 @)? -
谢谢@kennytm。 COALESCE 似乎将性能提高了一点点,但代码看起来仍然更好。
-
也感谢@Dario。删除子查询中的 ORDER BY 将性能提高了 13%。 call_sign 永远不会为空,但可能是 call_sign 存在于第一个表 (combo_fr) 或第二个表 (market_mf) 中,我想同时提取两者。这有帮助吗?
标签: postgresql join processing-efficiency