因为它很容易在Debian stable上安装,所以我决定使用PostgreSQL 9.6为我需要处理的一些数据构建一个数据仓库。第一步是使用最少的转换将数据加载到数据库中,主要是纠正一些已知的格式错误以及如何表示布尔值。我已经检查过这些更正是有效的:将n
行写入磁盘需要的时间与n
成比例。
但是,使用PostgreSQL的COPY FROM
(无论如何; \copy
,或psycopg2 copy_expert
或COPY FROM '/path/to/data.csv'
)批量加载此数据需要超线性的时间。渐近时间复杂度似乎比O(exp(sqrt(n)))
稍好一些。这已经是我的复杂性了:
READ UNCOMMITTED
和DEFERRED
。以下是我遇到的最严重的罪犯之一,17M排表:
禁用fsync
会使进程加速10倍,因此I / O显然是一个巨大的瓶颈。然而,除此之外,时间行为并没有那么大的改变:
当我使用代理键而不是业务键时,完全这个问题就消失了:当我使用自动递增整数列作为主键时,摄取需要{ {1}}再一次,这就是我想要的。因此,我不仅对我的问题有一个完全有效的解决方法,而且我也知道复杂的主键是罪魁祸首(业务键通常是短VARCHAR列的元组)。
但是,我想了解为什么PostgreSQL花费这么长的时间才能通过业务密钥输入数据,以便我更好地理解我的工具。特别是,我不知道如何调试此提取过程,因为Θ(n)
不适用于EXPLAIN
。对于复合主键,将数据排序到存储中可能需要更长时间,或者这是由于索引,或者主键约束实际上仍然是COPY
;如果解决方法不是那么有效,或出于其他原因而不受欢迎,我怎样才能发现这里的实际情况?