我有以下架构: 表A 名称
表B 名称
从TableB.Name到TableA.Name的外键
我将2500条记录插入表B,将一条记录插入TableA。
然后我发出更新声明“更新TableB set Name ='new',其中Name ='old'”。然后,我发出update语句,在同一事务中将TableA.Name从'old'更改为'new'。
我在TableB的更新语句周围放置了时序代码,发现使用外键时,执行更新语句需要9.7秒。没有外键,大约需要300毫秒。此外,如果我有FK,然后在更新TableB之前禁用它,然后在整个测试之后立即重新启用它,就像没有首先使用FK一样快。
除了时间之外,查询计划在上述方案中完全相同。在某些情况下,时间从大约11到33左右不等,当我有FK时,索引的数量会增加1。
我还发现,在整个时间内使用FK并在Name上添加一个索引,并且在任何查询中都没有使用其中一个布尔列也会导致快速更新语句大约300毫秒 - 400毫秒。
同样从TableB中删除一些不属于任何其他表的FK或PK的列(即,除了初始插入之外的任何查询中都不使用的列)再次提高了速度更新。
我已经尝试了很多东西,我不确定为什么这种行为在德比中如此糟糕。我只在整个表中处理2500行。更新索引不应该这么慢。我尝试分析查询计划(除了较慢的计时统计数据,它们是相同的),我试图强制更新统计数据。强制将数据刷新到Derby的磁盘。我尝试使用外部数据库浏览器并运行相同的更新语句(上面提到的2)并且速度相同。我还尝试了很多其他的东西。
行为始终与相同的测试场景一致(例如,在更新之前禁用外键),但这完全不合逻辑。为什么只更新2500行的FK更慢,这使得数据库无法使用。为什么在Name列上创建索引和完全不相关的列可以提高性能。
在开头附近的查询计划中的“执行时间:”总是一个很大的负数,但是下面的时间戳显示总编译和执行时间对于我正在观察的内容是正确的如果我减去它们。德比出了什么问题?为什么时间消极?
我也在Apache Derby 10.12.1.1的最新版本上,我只是作为诊断步骤尝试,因为当我发现这种行为时我在10.11.1.1上。
我真的很感激这方面的很多帮助。
由于