Postgres 9.4で大きな(1.2 TB)静的テーブルの部分インデックスを作成しようとしています。
私のデータは完全に静的なので、すべてのデータを挿入してから、すべてのインデックスを作成できます。
この1.2 TBのテーブルrun_id
には、データをきれいに分割するという名前の列があります。さまざまなをカバーするインデックスを作成することにより、優れたパフォーマンスを得ていますrun_id
。次に例を示します。
CREATE INDEX perception_run_frame_idx_run_266_thru_270
ON run.perception
(run_id, frame)
WHERE run_id >= 266 AND run_id <= 270;
これらの部分インデックスにより、望ましいクエリ速度が得られます。残念ながら、各部分インデックスの作成には約70分かかります。
CPUが制限されているようです(top
プロセスの100%を示しています)。
部分インデックスの作成を高速化するために何かできることはありますか?
システム仕様:
- 18コアXeon
- 192GB RAM
- RAIDに12個のSSD
- 自動バキュームがオフになっています
- maintenance_work_mem:64GB(高すぎる?)
テーブル仕様:
- サイズ:1.26 TB
- 行数:10537億
- 一般的なインデックスサイズ:3.2GB(〜.5GBの差異があります)
テーブル定義:
CREATE TABLE run.perception(
id bigint NOT NULL,
run_id bigint NOT NULL,
frame bigint NOT NULL,
by character varying(45) NOT NULL,
by_anyone bigint NOT NULL,
by_me bigint NOT NULL,
by_s_id integer,
owning_p_id bigint NOT NULL,
obj_type_set bigint,
seq integer,
subj_id bigint NOT NULL,
subj_state_frame bigint NOT NULL,
CONSTRAINT perception_pkey PRIMARY KEY (id))
(列名を読みすぎないようにしてください-多少難読化しました。)
背景情報:
- このデータを使用する別のチームがオンサイトにいますが、実際には1人または2人のユーザーしかいません。(このデータはすべてシミュレーションによって生成されます。)ユーザーは、挿入が完了し、インデックスが完全に構築されて初めて、データの分析を開始します。私たちの主な関心事は、使用可能なデータを生成するために必要な時間を削減することです。そして現在、ボトルネックはインデックス作成時間です。
- パーシャルを使用する場合、クエリ速度は完全に適切です。実際、各インデックスがカバーする実行数を増やしても、十分なクエリパフォーマンスを維持できると思います。
- テーブルをパーティション分割する必要があると思います。私たちはそのルートをとる前に他のすべてのオプションを使い果たしようとしています。
completely static
どういう意味We have a separate team onsite that consumes this data
ですか?範囲run_id >= 266 AND run_id <= 270
またはテーブル全体にインデックスを付けますか?各インデックスの平均余命はどれくらいですか?それを使用するクエリの数は?にはrun_id
いくつの異なる値がありますか?〜15ミオのように聞こえます。あたりの行数はrun_id
、約800の異なる値になりrun_id
ますか?なぜされているobj_type_set
、by_s_id
、seq
NOT NULL定義されていませんか?それぞれのおおよそのNULL値の割合はどれくらいですか?
run_id
でしょうか。均等に分散?ディスク上の結果のインデックスのサイズ?データは静的です。しかし、あなたは唯一のユーザーですか?