我正在尝试使用Hibernate在DB中插入记录。 数据将保存到DB中的多个表中。在休眠方面,我有一个父Entity类,它与其他Entity类进行一对一和一对多的映射。 在调试模式下,我可以看到保存操作导致多个sql插入。 第一个插入sql需要很长时间,大约300毫秒。 请注意:这不包括会话初始化,获取JDBC连接等所用的时间。 10:46:24.132 [main] DEBUG org.hibernate.SQL - 插入MY_SCHEMA_NAME.PARENT_ENTITY(COLUMN1,COLUMN2,COLUMN3,COLUMN4,COLUMN5,COLUMN6,COLUMN7,COLUMN8,COLUMN9,COLUMN10,COLUMN11,COLUMN12,COLUMN13,COLUMN14)值(?,?,?,?,?,?,?,?,?,?,?,?,?,?)
如果我从任何其他工具(Oracle SQL开发人员)执行,那么相同的SQL大约需要20毫秒。
hibernate执行的后续sql插件只需要大约15-20毫秒。
问题是,为什么Hibernate中的第一个sql插入需要花费这么多时间,与后续的sql插入相比差不多10倍?
答案 0 :(得分:0)
要回答这个问题,您需要学习:
简而言之:当SQL查询第一次从客户端发送到数据库 时,数据库在执行此语句之前会执行一些额外的步骤(请参阅第一个链接) )。在这第一次之后,此语句的sql计划被放入共享池(缓存类型),并且数据库可以跳过一些最耗时的任务(硬解析 - 优化和行源生成)以用于所有后续请求此具体查询 - 此过程称为"软解析"在上图链接的图表中
如果清除了共享池(例如在数据库重新启动后),则必须再次对第一个传入查询重复这些步骤 - 这需要额外的时间。
当查询引用的某些表/视图发生更改时(例如,在ALTER TABLE命令或CREATE / DROP INDEX命令之后),该语句将从缓存中刷新,并且数据库在此之后再次执行硬解析,并且此操作又一次。
在客户端,当语句第一次执行 时,它将被放置在缓存中(请参阅第二个链接) - 这需要一些额外的时间。在此之后,对于所有后续语句调用,将从缓存中检索语句 - 这样可以提高性能
关闭数据库驱动程序时(例如,在应用程序重新启动时),将清除缓存,并且下一次语句调用必须再次花费一些时间。
您可以明确地禁用语句缓存(请参阅第二个lnk以获取详细说明),并且您很可能会看到所有已执行的语句将花费更多时间。