为什么在Postgresql上设置所有延迟的约束需要很长时间?

为什么在Postgresql上设置所有延迟的约束需要很长时间?,postgresql,Postgresql,我们的Postgres 9.2.4服务器平均执行0.69秒(15000条语句) SET CONSTRAINTS ALL DEFERRED 为什么会这样 在表定义中使用初始延迟,而不使用设置约束..会消除这一次还是将其隐藏在其他地方?Imho,这可能是因为每次运行此语句时,后台都会出现一个关于pg_目录中表定义的大型更新语句。换句话说,您将死行添加到pg_目录中,这会导致在适当的顺序扫描期间访问越来越多的磁盘空间 如果您真的每天运行该语句1.5万次,那么您可能需要仔细查看您的模式或工作流?我查

我们的Postgres 9.2.4服务器平均执行0.69秒(15000条语句)

SET CONSTRAINTS ALL DEFERRED 
为什么会这样


在表定义中使用
初始延迟
,而不使用
设置约束..
会消除这一次还是将其隐藏在其他地方?

Imho,这可能是因为每次运行此语句时,后台都会出现一个关于pg_目录中表定义的大型更新语句。换句话说,您将死行添加到pg_目录中,这会导致在适当的顺序扫描期间访问越来越多的磁盘空间


如果您真的每天运行该语句1.5万次,那么您可能需要仔细查看您的模式或工作流?

我查看了源代码。本质上,
SET CONSTRAINTS ALL DEFERRED
除了设置一个全局变量并注明“所有适当的约束现在都被延迟”之外,什么也不做。唯一要做的非平凡工作是当有子事务在起作用时。如果这适用于你的情况,那就不必担心了。(请注意,子事务包括PL/pgSQL异常块。)

您是如何测量该时间的?这是否包括客户端/服务器通信开销?为什么这是一个问题呢?您多久运行一次该语句?时间是通过使用pgfouine分析日志文件来测量的,即Postgres报告的服务器端时间。一天执行15000次,总共需要3小时以上。此服务器正在插入/更新多批行,我们正在尝试提高吞吐量。您究竟为什么每天执行此语句15000次?它在每个批插入/更新事务开始时执行。插入/更新的行相互引用,因此我们需要这样做,以避免在每次插入/更新时绊倒约束。如果对每个事务都发出此命令,那么为什么不将所有约束设置为“最初延迟”?啊哈。这是否意味着在表定义中使用“INITIALLY DEFERRED”可以解决这个问题?该数据库在大约100个模式中有5000多个表。我假设“设置所有延迟的约束”只会设置一个per tx标志,而且速度很快。从技术上讲,您并没有错。它实际上是在每次编辑表(来回)时为每个约束设置一个标志。问题是,每个被更改的约束都有一个标志。这是大量的更新(即删除+插入)语句;换句话说,磁盘访问。是的,如果可以解决您的问题,那么在适当的情况下使用可延迟的初始延迟约束。这是不正确的。“设置约束不涉及系统目录。@DavidTinker:如果您将此挂起,您可能应该查看(并接受)Peter的响应。嗯。对我们来说,“设置所有延迟的约束”平均每笔交易花费0.69秒。据我所知,我们没有使用子事务(即,不是故意的)。我们正在使用PostgresJDBC驱动程序,所以这可能是在做些什么。如果这是一个线索,我们还会在日志中得到“事务已在进行中”警告。我们现在使用“最初延迟”解决了这个问题。