你好,我的问题是关于优化 sql 查询。 以下查询很慢:
SELECT id, name,
, (SELECT rank_time FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1)::date AS rank_time
, (SELECT host_c FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS host_c
, (SELECT index_pa FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pa
, (SELECT links_pa FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pa
, (SELECT index_pb FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS index_pb
, (SELECT links_pb FROM stage_rank WHERE stage = stage.id ORDER BY rank_time DESC LIMIT 1) AS links_pb
FROM stage
ORDER BY name;
我认为这主要是因为从 stage_rank
中重复选择,是否可以让这个选择完成一次,并一次获得所有字段?
还有任何 postgresql 特定的功能在这里可能有帮助吗?
最佳答案
在PostgreSQL
中,您可以选择整条记录作为一个字段,稍后展开:
SELECT id, name, (sr).*
FROM (
SELECT id, name,
(
SELECT stage_rank
FROM stage_rank
WHERE stage = stage.id
ORDER BY
rank_time DESC
LIMIT 1
) sr
FROM stage
) q
ORDER BY
name
或重写查询:
SELECT DISTINCT ON (s.name, s.id, sr.rank_time, sr.id)
s.id, s.name, sr.*
FROM stage s
JOIN stage_rank sr
ON sr.stage = s.id
ORDER BY
s.name, s.id, sr.rank_time DESC, sr.id DESC
或者换一种方式重写:
SELECT id, name, (sr).*
FROM (
SELECT s.id, s.name, sr, ROW_NUMBER() OVER (PARTITION BY s.id ORDER BY sr.rank_time DESC, sr.id DESC) rn
FROM stage
JOIN stage_rank sr
ON sr.stage = s.id
) q
WHERE rn = 1
ORDER BY
name
关于SQL将多个相似的子查询压缩成单个子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10651330/