私のラップトップには6GBのRAM=があり、テストのためにPostgreSQL 9.3で50mil行のテーブルを作成しています。次に、テーブルにインデックスを作成します。
テーブルと結果のインデックスを一緒に(またはテーブルの合計サイズの2倍)は、5 GBのRAMであり、maintenance_work_mem
を5GBに設定しても、CREATE INDEX
は外部ソートを使用します約1.4GBの一時ファイルがありますが、なぜですか?
RAM=でソートできるはずだと私は期待していますか?
test=# set maintenance_work_mem to '5GB';
SET
test=# create table t1 as (select i::int, random() as f from generate_series(1, 50000000) i);
SELECT 50000000
test=# select pg_size_pretty(pg_relation_size('t1'));
pg_size_pretty
----------------
2111 MB
(1 row)
test=# create index on t1(f, i);
CREATE INDEX
test=# select pg_size_pretty(pg_relation_size('t1_f_i_idx'));
pg_size_pretty
----------------
1504 MB
(1 row)
サーバーログ:
LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp22623.1", size 1073741824
STATEMENT: create index on t1(f, i);
LOG: temporary file: path "base/pgsql_tmp/pgsql_tmp22623.2", size 327622656
LOG: external sort ended, 171065 disk blocks used: CPU 6.78s/268.73u sec elapsed 313.18 sec
実際に実行する前にCREATE INDEX
のメモリ要件を計算する方法はありますか?
バージョン9.3まで、並べ替えに使用される間接配列は、1 GBの単一メモリ割り当てに収まる必要がありました。これにより、メモリ内でソートできるタプルの数に人為的な制限が作成されました。この制限に達すると、メモリが残っていても、ディスクソートに切り替える必要がありました。
この制限はバージョン9.4で削除されました。