3

良い一日、私の質問は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、この選択を1回実行して、すべてのフィールドを1回のヒットで取得することは可能ですか?

また、postgresql固有の機能がここで役立つ可能性がありますか?

4

1 に答える 1

9

では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
于 2012-05-18T10:59:04.250 に答える