由于FK触发器,PostgreSQL偶尔会降低插入速度

时间:2019-01-10 13:26:42

标签: postgresql postgresql-9.5

我有两个主子关系表(每个主子有几个孩子)。

在一个用例中,需要将带有所有子项的母版复制为新的母版。为此,我使用两个select + insert查询-一个用于复制主记录,另一个用于复制子记录。

问题:即使在数据库状态完全相同的情况下,用于复制子记录的查询有时也会很快(50毫秒),有时非常慢(1500毫秒)(我在每次测试前都会清除所有表) )。我找不到任何模式。有时连续几次慢,有时连续几次快,有时快,慢,快,慢。有时在数据库重新启动后很快,有时很慢。我正在测试单个并发客户端。

对于两个查询,我都得到了explain analyze的结果-整个差异来自于将子表与主表连接的外键:

  • 触发约束fk_attribute_value_element_id:time = 1109.641 调用= 1436

vs

  • 触发约束fk_attribute_value_element_id:time = 9.779 调用= 1436

看起来像Postgres,在验证新的子记录时,有时能够轻松地(最近插入)查找父记录,有时却不然。

有什么想法可以进一步调试吗?如何使插入始终快速?

我在Ubuntu 18.04中拥有PostgreSQL 9.6.11。

更新:

这是第一个查询,它复制了母版(此查询总是很快的):

insert into element
    (id, code, parent_code, hierarchy, version_id, version)
select 
    nextval('element_seq'), 
    e.code, 
    e.parent_code, 
    e.hierarchy, 
    :new_version_id, 
    e.version 
from element e
where e.version_id = :old_version_id

这是第二个查询,它复制子级(有时太慢了):

insert into attribute_value
    (id, language, value, attribute_description_id, element_id, version)
select  
    nextval('attribute_value_seq') as id,
    old_av.language,
    old_av.value,
    old_av.attribute_description_id,
    new_e.id as element_id,
    old_av.version
from element old_e
join element new_e on new_e.version_id = new_version_id and new_e.code = old_e.code
join attribute_value old_av on old_av.element_id = old_e.id
where old_e.version_id = :old_version_id

以下是第二个查询的explain (analyze, buffers)个结果(左=慢,右=快):https://www.diffchecker.com/lBA6sgaf

慢速FK将attribute_value.element_idelement.id相关。

0 个答案:

没有答案