我写的这个问题就在这里:
http://www.philliphaydon.com/2011/09/the-benefits-of-letting-the-orm-generate-the-identity-part-1/
如果您使用的是在数据库中生成IDENTITY
或GUID
S,你会从缓慢插入受苦,无法批。
当使用GUID插入到SQL中时,NHibernate首先发出请求以获取新的GUID。
您与交易结束了,像这样:
- statement #1
begin transaction with isolation level: Unspecified
- statement #2
select newid()
- statement #3
select newid()
- statement #4
select newid()
- statement #5
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple0' /* @p0_0 */,
'269bc638-74b4-4568-85d1-45b6e537fcbd' /* @p1_0 */)
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple1' /* @p0_1 */,
'fc848779-b173-4c31-b8b6-0a7735c0c2dc' /* @p1_1 */)
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple2' /* @p0_2 */,
'232c8971-18c7-486d-9152-26c969c3b632' /* @p1_2 */)
- statement #6
commit transaction
同样,当您使用的身份,NHibernate的需要选择新的ID背出数据库中的更新模型,这是特别重要的,当NHibernate的需求在插入前将这个新对象与另一个对象联系起来
使用IDENTITY结束了与交易看起来像:
- statement #1
begin transaction with isolation level: Unspecified
- statement #2
INSERT INTO People
(FirstName,
Surname)
VALUES ('Phillip0' /* @p0 */,
'Haydon' /* @p1 */);
select SCOPE_IDENTITY()
- statement #3
INSERT INTO People
(FirstName,
Surname)
VALUES ('Phillip1' /* @p0 */,
'Haydon' /* @p1 */);
select SCOPE_IDENTITY()
- statement #4
INSERT INTO People
(FirstName,
Surname)
VALUES ('Phillip2' /* @p0 */,
'Haydon' /* @p1 */);
select SCOPE_IDENTITY()
- statement #5
commit transaction
一个相当不错的计算机上运行一些基本的测试我插结果与下面的时序:
- IDENTITY 28951ms
- NEWID 30241ms
将此更新为使用HiLo或G uidComb允许NHibernate自己生成身份。
使用HiLo,NHibernate会发出一个下一个hi值的请求,然后更新hi值,一旦有hi就可以生成一系列的Ids,直到lo满了。
这导致插入像这样:
- statement #1
begin transaction with isolation level: Unspecified
- statement #2
Reading high value:
select next_hi
from hibernate_unique_key with (updlock, rowlock)
- statement #3
Updating high value:
update hibernate_unique_key
set next_hi = 3 /* @p0 */
where next_hi = 2 /* @p1 */
- statement #4
INSERT INTO People
(FirstName,
Surname,
Id)
VALUES ('Phillip0' /* @p0_0 */,
'Haydon' /* @p1_0 */,
202 /* @p2_0 */)
INSERT INTO People
(FirstName,
Surname,
Id)
VALUES ('Phillip1' /* @p0_1 */,
'Haydon' /* @p1_1 */,
203 /* @p2_1 */)
INSERT INTO People
(FirstName,
Surname,
Id)
VALUES ('Phillip2' /* @p0_2 */,
'Haydon' /* @p1_2 */,
204 /* @p2_2 */)
- statement #5
commit transaction
同样使用GuidComb,NHibernate的会生成一个GUID为您:
- statement #1
begin transaction with isolation level: Unspecified
- statement #2
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple0' /* @p0_0 */,
'db902160-edbb-49c7-bf52-9f660018299a' /* @p1_0 */)
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple1' /* @p0_1 */,
'5e852528-3a6f-41d2-a6b1-9f660018299a' /* @p1_1 */)
INSERT INTO Fruit
(Name,
Id)
VALUES ('Apple2' /* @p0_2 */,
'2f63c6e8-e595-4393-ad15-9f660018299a' /* @p1_2 */)
- statement #3
commit transaction
这意味着NHibernate的不需要往返数据库在执行插入操作时,这两个操作都允许发生批量插入操作,就像您在HiLo和GuidComb中看到的那样,只有一条语句被发送到服务器,而不像NEWID/IDENTITY那样为每个插入语句发送语句,每个新的ID都被制成。
这导致像低得多的时间:
我希望帮助:)
设置BATCHSIZE大型也会影响检索性能消极我认为。在这种情况下,无状态会话不是一种选择,因为这意味着我们失去了大部分INSERT和UPDATE语句的级联。 – Pieter