Hibernate IDENTITY与SEQUENCE实体标识符生成器

coo*_*per 11 java performance hibernate jpa java-ee

"与标识不同,列值的下一个数字将从内存而不是从磁盘中检索- 这使得序列明显快于本文中定义的"身份" .这是否意味着id来自磁盘,如果是身份,如果是,则是哪个磁盘以及如何.使用序列,我可以在日志中看到一个额外的选择查询到db同时插入一个新记录.但我没有在身份的情况下在日志中找到额外的选择查询.那么序列如何变得比身份更快.

有人可以提供有关这种复杂性的宝贵见解.

JB *_*zet 21

序列使用的策略:

在插入新行之前,请向数据库询问下一个序列值,然后插入此行,并返回序列值作为ID.

身份使用的策略:

插入行而不指定ID的值.插入行后,向数据库询问上次生成的ID.

因此,在两种情况下查询的数量都是相同的.但是,Hibernate默认使用一种对序列生成器更有效的策略.实际上,当它要求下一个序列值时,它会在内存中保留50(即dafault,IIRC和它可配置)下一个值,并在接下来的50个插入中使用这50个下一个值.只有在插入50次之后,它才会进入数据库以获得50个下一个值.这极大地减少了自动ID生成所需的SQL查询数量.

身份策略不允许这样的优化.


Vla*_*cea 17

IDENTITY发电机总是需要获取的主键值,而无需等待刷新到当前的同步数据库命中实体状态转换与数据库.

因此IDENTITY生成器与Hibernate后写一级缓存策略不兼容,因此对于IDENTITY生成器禁用JDBC批处理.

序列生成器可以从数据库值预分配中受益,您甚至可以使用HI/LO优化策略.

在我看来,最好的生成器是汇集和汇集的序列生成器.这些生成器将批处理友好的序列生成器与客户端值生成优化相结合,该优化与其他可能插入行而不了解我们生成策略的数据库客户端兼容.

无论如何,你永远不应该选择TABLE生成器,因为它执行得非常糟糕.如果您需要可移植性,可以使用重写配置来解决它,如本文所述.


gra*_*aci 0

虽然我个人对 Hibernate 很陌生,但据我所知,使用 Identity 基本上意味着 Hibernate 将从数据库中检查下一个可能的 id 值并为其保留一个值。

对于序列,您基本上告诉 Hibernate 根据您提供的特定序列生成下一个值。因此它必须通过查看下一个可能的 id 值来实际计算下一个 id。因此,额外的查询被触发。