Amy*_*Amy 8 postgresql postgresql-9.6
我有一个大型 Postgres 表,其中包含 2+ 十亿个条目(1.5TB),并且大部分是非空的 char var 列。为了加快插入速度,我在批量上传之前删除了索引。但是,现在创建 b 树索引需要很长时间。对于我缩短的运行之一,它花了超过 12 个小时创建索引。
我正在尝试制作的示例表和索引:
Column | Type | Modifiers
-----------------------+-----------------------------+-----------
name | character varying | not null
id | character varying |
lifecycle_id | character varying |
dt | character varying |
address | character varying |
...
Indexes:
"name_idx" PRIMARY KEY, btree (name)
"id_idx" btree (rec_id)
"lifecycle_id_idx" btree (lifecycle_id)
Run Code Online (Sandbox Code Playgroud)
实际表有 18 列。我已将 maintenance_work_mem 设置为 15GB。这是在 RDS 上的 Postgres 9.6.11 上运行的。实例类是 db.m4.4xlarge。
由于有三个索引,在插入之前很难对数据进行排序。只插入数据而不删除索引会更快吗?还有其他加快索引创建的建议吗?
创建索引的最佳调整方法是为 设定一个非常高的值maintenance_work_mem。
如果您只是向 1.5 TB 表中添加几百万行,则删除和重新创建索引可能会更慢。您必须运行测试来确定它开始变得更快的点。
在我发布这个问题之前,我运行了两个测试,但我不确定它们是否会完成。如果他们从未完成,我希望能深入了解如何加快速度。值得庆幸的是,其中一项测试确实完成了。通过尝试 jjanes 发布的建议,我也获得了不错的结果。
使用 Postgres 9,我运行了两个测试:
第一次测试已经运行了一周,仅插入了 20 亿个条目中的 20%。使用索引插入绝对不是要走的路。
第二次测试耗时 45 小时。在不知道创建索引需要多长时间的情况下,我过早地中断了之前的一些测试,并且从未看到它们完成。这需要很长时间,但就目前而言,我很高兴它不会永远持续下去。
根据 jjanes 的建议,我升级到 Postgres 11,将并行工作线程设置为 8,并将维护工作内存设置为 7GB。我按照本指南来选择参数:https : //www.cybertec-postgresql.com/en/postgresql-parallel-create-index-for-better-performance/。这加快了索引的创建,并且只用了 35 个小时。削减 10 个小时是一个不错的惊喜。谢谢!
PostgreSQL 在版本 10 中添加了并行化单个索引构建的功能,因此您可以考虑升级以利用此功能。
即使是您当前使用的版本,您也可以同时在同一个表上创建多个索引(使用不同的数据库连接来调用每个索引),因此您仍然可以进行某种程度的非正式并行化。您只能使用常规索引构建来执行此操作,这会在构建索引时锁定对表的更改。“并发”索引构建允许 UPDATE/INSERT/DELETE 与索引构建同时运行,但不允许同一表上的索引构建彼此并发。
根据我的经验,AWS 的虚拟 CPU 几乎没有用。虽然 db.m4.4xlarge 报告 16 个 vCPU,但并行化超过 8 个没有意义。如果您想利用并行性(v10 单索引,或者只是同时构建多个索引),您可能需要一个更小的maintenance_work_mem 的值大于 15GB。
只插入数据而不删除索引会更快吗?
在某些时候,肯定。这取决于您的批量插入中有多少记录,再加上一堆其他的东西,不能仅仅通过思考来回答。这是一个实验问题。
| 归档时间: |
|
| 查看次数: |
6940 次 |
| 最近记录: |