通常、Postgresクエリプランナーはします クエリ全体を最適化するための「インライン」ビュー。 ドキュメントごと:
しかし、私はPostgresが十分に賢いとは思いません 行を展開せずにベーステーブルから同じ結果に到達できると結論付けます。
LATERAL
を使用してこの代替クエリを試すことができます 加入。よりクリーンです:
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
, m.start_day + c.rn - 1 AS row_date
, c.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL unnest(m.counts) WITH ORDINALITY c(row_count, rn) ON true;
また、(end_day
、start_day
)は冗長です。
LEFT JOIN
の使用 これにより、クエリプランナーがクエリからの結合を無視できる可能性があるためです:
SELECT DISTINCT type FROM v_mt_count_by_day;
それ以外の場合(CROSS JOIN
またはINNER JOIN
)必須 結合を評価して、最初のテーブルの行が削除されているかどうかを確認します。
ところで、それは:
SELECT DISTINCT type ...
ない:
SELECT DISTINCT(type) ...
これはdate
を返すことに注意してください オリジナルのタイムスタンプの代わりに。簡単です、とにかくそれがあなたが望むものだと思いますか?
Postgresが必要9.3+ 詳細:
ROWS FROM
Postgres9.4以降
両方の列を並行して安全に爆発させるには :
CREATE OR REPLACE VIEW runinfo.v_mt_count_by_day AS
SELECT m.run_id, m.type, m.brand
t.row_date::date, t.row_count
FROM runinfo.mt_count_by_day m
LEFT JOIN LATERAL ROWS FROM (
unnest(m.counts)
, generate_series(m.start_day, m.end_day, interval '1d')
) t(row_count, row_date) ON true;
主な利点:2つのSRFが同じ数の行を返さない場合、これはデカルト積に脱線しません。代わりに、NULL値が埋め込まれます。
繰り返しになりますが、これがクエリプランナーがDISTINCT type
のより高速なプランを作成するのに役立つかどうかはわかりません。 テストなし。