在看pro jpa 2 这本书的时候,老外提到了 id 的生成策略如果是 identity 效率上会不如其他 id 预先生成好的策略(如 table,sequence),他解释说是 identity 策略只有在 insert 的时候才能知道分配的 id。我对此有一些疑惑,所以我对进行了一些测试,结果却有一些出人意料。
先说一下,我有这样一下非常简单的实体:@Entity
public class Foo {
@Id
private Long id;
private String bar; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
}
我对他进行这样的操作: EntityManager em =...; em.getTransaction().begin(); long start = System.nanoTime();
for (int i = 0; i < 1000; i++) { Foo foo = new Foo();
em.persist(foo);
}
long end = System.nanoTime();
em.getTransaction().commit();
System.out.println(end - start);这个对象保存1000次,对计算这个过程花费的时间。第一个测试场景,数据库为 mysql , jpa provider 用的是 eclipseLink ,Foo 实体的 id 的生成策略为 identity,得到如下结果:
第一次输出
22743952,
第二次输出
22258694
然后,其他的都没有变,我将策略变为 table,则得到如下结果:
第一次输出
471251235,
第二次输出
522187876这个结果出乎我的意料,竟然与老外说的相反。而且竟然差的这么远,identity 要比 table 的效率至少高一个数量级。我不知该如何解释,我怀疑可能是不是 jpa 实现的原因,我用的是 eclipseLink。所以我又其他的实现。第二个测试场景,只是 jpa provider 我换成了 hibernate ,其他的都更第一个测试场景情况一样,当 id 为 identity 时,得到如下结果:
第一次输出
1119812155,
第二次输出
1078923160然后我再将 id 的生成策略变为 table,则得到如下结果:
第一次输出
577731248,
第二次输出
640952970这次得到的结果却跟 eclipseLink 实现得到的结果也是相反的。所以我也不知道如何来解释这个。
有能指点小弟的,就请大家敞开说。
先说一下,我有这样一下非常简单的实体:@Entity
public class Foo {
@Id
private Long id;
private String bar; public Long getId() {
return id;
} public void setId(Long id) {
this.id = id;
}
我对他进行这样的操作: EntityManager em =...; em.getTransaction().begin(); long start = System.nanoTime();
for (int i = 0; i < 1000; i++) { Foo foo = new Foo();
em.persist(foo);
}
long end = System.nanoTime();
em.getTransaction().commit();
System.out.println(end - start);这个对象保存1000次,对计算这个过程花费的时间。第一个测试场景,数据库为 mysql , jpa provider 用的是 eclipseLink ,Foo 实体的 id 的生成策略为 identity,得到如下结果:
第一次输出
22743952,
第二次输出
22258694
然后,其他的都没有变,我将策略变为 table,则得到如下结果:
第一次输出
471251235,
第二次输出
522187876这个结果出乎我的意料,竟然与老外说的相反。而且竟然差的这么远,identity 要比 table 的效率至少高一个数量级。我不知该如何解释,我怀疑可能是不是 jpa 实现的原因,我用的是 eclipseLink。所以我又其他的实现。第二个测试场景,只是 jpa provider 我换成了 hibernate ,其他的都更第一个测试场景情况一样,当 id 为 identity 时,得到如下结果:
第一次输出
1119812155,
第二次输出
1078923160然后我再将 id 的生成策略变为 table,则得到如下结果:
第一次输出
577731248,
第二次输出
640952970这次得到的结果却跟 eclipseLink 实现得到的结果也是相反的。所以我也不知道如何来解释这个。
有能指点小弟的,就请大家敞开说。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货