Java 使用外键时Apache Derby数据库性能缓慢

Java 使用外键时Apache Derby数据库性能缓慢,java,derby,Java,Derby,我有以下模式: 表 名字 表B 名称 TableB.Name到TableA.Name的外键 我在表B中插入2500条记录,在表A中插入一条记录 然后我发出update语句“update TableB set Name='new'其中Name='old'”。然后,我发出update语句,在同一事务中将TableA.Name从'old'更改为'new' 我在TableB的update语句周围放了计时代码,发现使用外键执行update语句需要9.7秒。如果没有外键,大约需要300毫秒。另外,如果我有

我有以下模式: 表 名字

表B 名称

TableB.Name到TableA.Name的外键

我在表B中插入2500条记录,在表A中插入一条记录

然后我发出update语句“update TableB set Name='new'其中Name='old'”。然后,我发出update语句,在同一事务中将TableA.Name从'old'更改为'new'

我在TableB的update语句周围放了计时代码,发现使用外键执行update语句需要9.7秒。如果没有外键,大约需要300毫秒。另外,如果我有FK,然后在更新TableB之前禁用它,然后在整个测试之后重新启用它,这与没有FK一样快

除了计时之外,在上述场景中,查询计划完全相同。在某些情况下,时间从11到33左右不等,当我使用FK时,索引的数量增加了1

我还发现,始终使用FK,并在Name和一个布尔列上添加一个索引,而这些布尔列在任何查询中都没有使用,这也会导致大约300毫秒到400毫秒的快速更新语句

此外,从表B中删除一些不属于任何其他表的FK或PK的列(即,除了初始插入之外,甚至没有在任何查询中使用的列)也可以再次提高更新速度

我几乎什么都试过了,我不知道为什么德比的表现如此糟糕。我只处理整张桌子上的2500行。更新索引不应该这么慢。我尝试分析查询计划(除了较慢的计时统计数据外,它们是相同的),我尝试强制更新统计数据。为Derby强制将数据刷新到磁盘。我尝试使用一个外部数据库浏览器,运行相同的更新语句(上面提到的2条),但速度也一样慢。我还尝试了很多其他的东西

该行为始终与相同的测试场景一致(例如,在更新之前是否禁用外键),但这完全不合逻辑。为什么更新只有2500行的FK会这么慢,这会使数据库无法使用。为什么在Name列和完全无关的列上创建索引会提高性能

此外,查询计划中靠近开始处的“执行时间:”始终是一个很大的负数,但是下面显示编译和执行总时间的时间戳对于我所观察到的减去它们是正确的。德比有什么问题吗?为什么时间是负的

我还使用了ApacheDerby10.12.1.1的最新版本,我只是尝试将其作为诊断步骤,因为我在10.11.1.1上发现了这种行为

我真的非常感谢你在这件事上的帮助


谢谢

在这种情况下,您可以尝试使用表锁而不是默认的行锁。您可以将其构建为一个独立的测试程序来演示该行为吗?如果是这样,你可以在Derby问题跟踪器上用你的独立repo程序记录一个bug。你说用独立repo程序记录bug是什么意思?有人知道为什么Derby的行为如此不合逻辑,为什么时间统计是负数吗?这在我看来不正常。