2

数十億行のテーブルがあります。「タイムゾーンなしのタイムスタンプ」である「記録済み」フィールドには、毎日のパーティションがあります。現在表にある日を知りたいです。私は次のようなことができることを知っています:

SELECT recorded::date
FROM table
GROUP BY 1;

これは理想的には機能するはずですが、それに関する説明はかなり高く、機能するのにかなりの時間がかかることを示しています...それが私にできる最善のことであれば、それを受け入れることができます(データをそのまま監視することができます)入ります)、しかし、毎日のパーティション分割があることを考えると、これを行うためのより効率的な方法があるかどうか疑問に思っていましたか?

4

2 に答える 2

2

次のようなインデックスを作成できます。

create index your_index_name
on table (date_trunc('day', recorded))

私のテストでは、PostgreSQL 9.something は、インデックスを追加する前にシーケンシャル スキャンを使用し、単に「記録された」列にインデックスを付けた後にシーケンシャル スキャンを使用し、date_trunc() でインデックスを付けた後にインデックス スキャンを使用しました。1 日分の行を選択するには、インデックスなしで 66 ミリ秒、プレーン インデックスで 68 ミリ秒、date_trunc() を使用したインデックスで 13 ミリ秒かかりました。

何十億もの行があるため、そのインデックスの作成には数分かかることが予想されます。(咳)

于 2011-05-18T00:36:32.813 に答える
1

ここに非常によく似たスレッドがあります:

postgresで個別のクエリを選択するのが遅い

最小/最大の日付がわかっている場合は、テーブル全体に対して seq スキャンを実行するよりも、日付のリストに対してクエリを実行する方が適切です。記録されたインデックスがあると仮定すると、次のようなものの方が高速です。

with days as (
select date_trunc('day', min(recorded))::date + k * interval '1 day' as day
from records,
     generate_series(0,
                    (select date_trunc('day', max(recorded))::date
                            - date_trunc('day', min(recorded)::date
                    from records
     )) as k
)
select day
from days
where exists (
      select 1
      from records
      where day <= recorded and recorded < day + interval '1 day'
      );

上記のクエリを微調整する必要があるかもしれませんが、一般的な考え方はそこにあります。数十億の行を seq スキャンして、インデックス付きフィールドに対して数千回のサブクエリ/インデックス スキャンを実行する方が高速です。異なる日を識別するためにそれらを集計します。

于 2011-05-18T01:58:01.423 に答える