我的笔记本电脑上有 6GB 的 RAM,为了进行测试,我正在 PostgreSQL 9.3 中创建一个 5000 万行的表。然后我想在表上创建一个索引。
表和生成的索引一起(或表总大小的两倍)可以放入 5GB 的 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 版,用于排序的间接数组必须适合单个 1GB 内存分配。这人为地限制了可以在内存中排序的元组的数量。一旦达到这个限制,它就必须切换到磁盘排序,即使还有剩余的内存。
此限制在 9.4 版中已删除。