简体   繁体   English

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

[英]Hibernate IDENTITY vs SEQUENCE entity identifier generators

This article says:这篇文章说:

Unlike identity, the next number for the column value will be retrieved from memory rather than from the disk – this makes Sequence significantly faster than Identity与 identity 不同的是,列值的下一个数字将从内存而不是从磁盘中检索——这使得 Sequence 比 Identity 快得多

Does it mean that ID comes from disk in case of identity?在身份的情况下,这是否意味着 ID 来自磁盘? If yes, then which disk and how ?如果是,那么哪个磁盘以及如何

Using sequence, I can see in the log, an extra select query to DB while inserting a new record.使用序列,我可以在日志中看到,在插入新记录时对数据库进行了额外的选择查询。 But I didn't find that extra select query in the log in case of identity.但是我没有在日志中发现额外的选择查询,以防万一。 Then how sequence becomes faster than identity ?那么序列如何变得比身份更快

Strategy used by sequence:序列使用的策略:

Before inserting a new row, ask the database for the next sequence value, then insert this row with the returned sequence value as ID.在插入新行之前,向数据库询问下一个序列值,然后将返回的序列值作为 ID 插入该行。

Strategy used by identity:身份使用的策略:

Insert a row without specifying a value for the ID.插入一行而不指定 ID 的值。 After inserting the row, ask the database for the last generated ID.插入行后,向数据库询问最后生成的 ID。

The number of queries is thus the same in both cases.因此,两种情况下的查询数量相同。 But , Hibernate uses by default a strategy that is more efficient for the sequence generator.但是,Hibernate 默认使用一种对序列生成器更有效的策略。 In fact, when it asks for the next sequence value, it keeps th 50 (that's the dafault, IIRC, and it's configurable) next values in memory, and uses these 50 next values for the next 50 inserts.事实上,当它请求下一个序列值时,它会在内存中保留 50 个(这是 dafault,IIRC,它是可配置的)下一个值,并在接下来的 50 个插入中使用这 50 个下一个值。 Only after 50 inserts, it goes to the database to get the 50 next values.只有在 50 次插入后,它才会进入数据库以获取 50 个下一个值。 This tremendously reduces the number of needed SQL queries needed for automatic ID generation.这极大地减少了自动 ID 生成所需的 SQL 查询数量。

The identity strategy doesn't allow for such an optimization.身份策略不允许这样的优化。

The IDENTITY generator will always require a database hit for fetching the primary key value without waiting for the flush to synchronize the current entity state transitions with the database. IDENTITY生成器将始终需要数据库命中来获取主键值,而无需等待刷新以将当前实体状态转换与数据库同步。

So the IDENTITY generator doesn't play well with Hibernate write-behind first level cache strategy, therefore JDBC batching is disabled for the IDENTITY generator.因此IDENTITY生成器不能很好地与 Hibernate 后写一级缓存策略配合使用,因此IDENTITY生成器禁用了 JDBC 批处理。

The sequence generator can benefit from database value preallocation and you can even employ a hi/lo optimization strategy.序列生成器可以从数据库值预分配中受益,您甚至可以采用hi/lo优化策略。

In my opinion, the best generators are the pooled and pooled-lo sequence generators.在我看来,最好的生成器是pooledpooled-lo序列生成器。 These generators combine the batch-friendly sequence generator with a client-side value generation optimization that's compatible with other DB clients that may insert rows without knowing anything about our generation strategy.这些生成器将批处理友好的序列生成器与客户端值生成优化相结合,该优化与其他可能在不了解我们的生成策略的情况下插入行的数据库客户端兼容。

Anyway, you should never choose the TABLE generator because it performs really bad.无论如何,您永远不应该选择TABLE生成器,因为它的性能非常糟糕。

Though I'm personally new to Hibernate, from what I can recall, using Identity basically means that Hibernate will check what is the next possible id value from your DB and keep a value for it.虽然我个人是 Hibernate 的新手,但据我所知,使用 Identity 基本上意味着 Hibernate 将检查您的数据库中下一个可能的 id 值是什么,并为其保留一个值。

For sequence, you basically tell Hibernate to generate the next value based on a particular sequence you provide it.对于序列,您基本上是告诉 Hibernate 根据您提供的特定序列生成下一个值。 So it has to actually calculate the next id by looking at the next possible id value.所以它必须通过查看下一个可能的 id 值来实际计算下一个 id。 Hence, the extra query is fired.因此,会触发额外的查询。

maybe this will answer your question :也许这会回答你的问题:

Unlike identity column values, which are generated when rows are inserted, an application can obtain the next sequence number before inserting the row by calling the NEXT VALUE FOR function.与插入行时生成的标识列值不同,应用程序可以在插入行之前通过调用 NEXT VALUE FOR 函数获取下一个序列号。 The sequence number is allocated when NEXT VALUE FOR is called even if the number is never inserted into a table.即使编号从未插入表中,在调用 NEXT VALUE FOR 时也会分配序列号。 The NEXT VALUE FOR function can be used as the default value for a column in a table definition. NEXT VALUE FOR 函数可用作表定义中列的默认值。 Use sp_sequence_get_range to get a range of multiple sequence numbers at once.使用 sp_sequence_get_range 一次获取多个序列号的范围。

you can find the detail here你可以在这里找到详细信息

Identity doesnt need that extra select query because Identity is a table dependent and Sequence is independent from table, but because of this we can get sequence even before creating a row(when you do session.save(T entity), sequence is generated even before you commit the transaction). Identity 不需要额外的 select 查询,因为 Identity 是一个表依赖而 Sequence 独立于表,但因此我们甚至可以在创建行之前获得序列(当你执行 session.save(T entity) 时,序列甚至在之前生成您提交交易)。

sequence : you create or update entities -> each time you save entity -> hibernate get next sequence value -> your program return the value after all process complete without exception or rollback -> you commit all transaction -> hibernate insert all complete entity序列:您创建或更新实体-> 每次保存实体时-> 休眠获取下一个序列值-> 您的程序在所有进程完成后无异常或回滚后返回该值-> 您提交所有事务-> 休眠插入所有完整实体

identity : when commit transaction, insert incomplete entity(must get it from identity column).身份:提交事务时,插入不完整的实体(必须从身份列中获取)。 so the INSERT command of sequence is definitely slower, but the advantages is if you cancel the insert the count doesn't increasing.所以序列的INSERT命令肯定更慢,但优点是如果取消插入,计数不会增加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM