什么减慢了我的PostgreSQL批量导入?

时间:2018-01-02 16:47:53

标签: postgresql constraints data-ingestion

因为它很容易在Debian stable上安装,所以我决定使用PostgreSQL 9.6为我需要处理的一些数据构建一个数据仓库。第一步是使用最少的转换将数据加载到数据库中,主要是纠正一些已知的格式错误以及如何表示布尔值。我已经检查过这些更正是有效的:将n行写入磁盘需要的时间与n成比例。

但是,使用PostgreSQL的COPY FROM(无论如何; \copy,或psycopg2 copy_expertCOPY FROM '/path/to/data.csv')批量加载此数据需要超线性的时间。渐近时间复杂度似乎比O(exp(sqrt(n)))稍好一些。这已经是我的复杂性了:

  • 将隔离级别设置为READ UNCOMMITTED
  • 将主键约束设置为DEFERRED

以下是我遇到的最严重的罪犯之一,17M排表:

Square root of number of rows appears proportional to the logarithm of ingestion time when fsync is on

禁用fsync会使进程加速10倍,因此I / O显然是一个巨大的瓶颈。然而,除此之外,时间行为并没有那么大的改变:

Square root of number of rows also appears proportional to the logarithm of ingestion time when fsync is off

当我使用代理键而不是业务键时,完全这个问题就消失了:当我使用自动递增整数列作为主键时,摄取需要{ {1}}再一次,这就是我想要的。因此,我不仅对我的问题有一个完全有效的解决方法,而且我也知道复杂的主键是罪魁祸首(业务键通常是短VARCHAR列的元组)。

但是,我想了解为什么PostgreSQL花费这么长的时间才能通过业务密钥输入数据,以便我更好地理解我的工具。特别是,我不知道如何调试此提取过程,因为Θ(n)不适用于EXPLAIN。对于复合主键,将数据排序到存储中可能需要更长时间,或者这是由于索引,或者主键约束实际上仍然是COPY;如果解决方法不是那么有效,或出于其他原因而不受欢迎,我怎样才能发现这里的实际情况?

0 个答案:

没有答案