为啥 H2 DB FileLock.sleep() 需要这么长时间?
Posted
技术标签:
【中文标题】为啥 H2 DB FileLock.sleep() 需要这么长时间?【英文标题】:Why does H2 DB FileLock.sleep() need to take so long?为什么 H2 DB FileLock.sleep() 需要这么长时间? 【发布时间】:2014-03-31 01:46:10 【问题描述】:我今天早些时候在评估 H2 的速度,发现在进行许多后续查询时速度明显放缓。我用 JMX 做了一个快速的 CPU 配置文件,我注意到大部分 CPU 时间都花在了FileLock.sleep()
方法上。我在进行数百条 INSERT 语句时调试了代码,这些调用几乎完全源于 FileLock.lockFile()
方法中的这一行:
save();
sleep(SLEEP_GAP);
FileLock.SLEEP_GAP
是 static final int
设置为 25,所以它根本无法调整(请不要建议我使用反射,如果您认为这会起作用,我鼓励您使用 read this answer )。调用此方法并导致主线程在执行的每个 INSERT 语句上休眠 25 毫秒。如果你有数以万计的程序要执行,那真的会浪费很多时间。为什么这个值是这样设置的?有什么办法可以不用这个类吗?
Source code,如果您不想将其从 SVN 中取出。
【问题讨论】:
你打开和关闭连接很多,而且只有一个连接吗?在那种情况下,数据库文件被打开和关闭很多,这很慢(不管睡眠间隙有多小)。在这种情况下,我会考虑保持连接打开,或者使用连接池。或者,更简单,将";DB_CLOSE_DELAY=1"
附加到数据库 URL。
我正在使用 Spring 来管理数据源,因此它可能会频繁地打开/关闭连接。不知道是否有办法让它在关闭它时更加保守,但我今晚回家时会试试这个参数。
天哪,这产生了巨大的不同;将 400 条记录加载到大约 1 秒需要 20 秒。请给出答案,以便我接受!
【参考方案1】:
FileLock.sleep()
在打开数据库文件时使用,以确保没有其他进程可以同时打开同一个数据库文件(类似于文件锁定)。大多数数据库引擎都使用这种机制。如果您在分析中看到这一点,那么这意味着数据库连续多次打开和关闭。打开和关闭数据库非常慢,应该避免。
如果可能,数据库应保持打开状态,by keeping the connection open or by using a connection pool。
如果这不是一个选项,则将 ;DB_CLOSE_DELAY=1
附加到数据库 URL。这将使数据库文件在关闭最后一个连接后保持打开一秒钟。
【讨论】:
我想为后人补充一点,Spring 不会使用默认配置自行保持连接打开。以上是关于为啥 H2 DB FileLock.sleep() 需要这么长时间?的主要内容,如果未能解决你的问题,请参考以下文章