向标准添加简单键时,扭矩 4 性能真的很慢
Really slow torque 4 performance when adding simple key to criteria
我在扭矩方面遇到了一个非常奇怪的性能问题。看看下面的循环。 运行 需要 13 秒。
但是如果我替换这条线
c.and(PicturePeer.ID,SimpleKey.keyFor(2072));
和
c.and(PicturePeer.ID,2072);
相同的循环 运行s 在 0.2 秒内。这没有意义,因为它是完全相同的操作,即获取 id=2072;
的图片
我什至在我的 PostgreSQL 数据库上启用了完整的查询日志,并且当我更改我使用的 2 个 c.add 方法中的哪一个时,对数据库的 select 查询不会改变。所以我不明白为什么没有 SimpleKey 的第二个解决方案比第一个快 50 倍。
我发现的原因是
c.and(PicturePeer.ID,SimpleKey.keyFor(2072))
是 retrieveByPK 使用的方法,它会破坏我的性能。
con = Transaction.begin();
long start=System.currentTimeMillis();
for(int i=0;i!=1000;i++) {
Criteria c=new Criteria();
c=new Criteria();
c.and(PicturePeer.ID,SimpleKey.keyFor(2072));
// c.and(PicturePeer.ID,2072);
PicturePeer.doSelect(c,con);
}
long end=System.currentTimeMillis();
long diff=end-start;
System.out.println("Load diff=" + diff);
con.rollback();
来自 schema.xml 的图片关系如下所示:
<table name="picture" idMethod="native">
<column name="id" primaryKey="true" required="true" type="INTEGER"/>
<column name="filename" required="true" type="VARCHAR"/>
<column name="name" required="true" type="VARCHAR"/>
<column name="description" required="true" type="VARCHAR"/>
<column name="role" required="true" type="VARCHAR"/>
</table>
如果我在标准上调用 setLimit(1),使用 SimpleKey 的慢速方法与快速方法一样快,所以看起来 postgresql 正在使用 table 扫描,这毫无意义大部头书。特别是因为没有限制的慢速和快速版本给出了完全相同的查询日志。
这是来自 postgresql 的完整日志。 (select 2 是验证连接的东西)。
LOG: execute <unnamed>: SET extra_float_digits = 3
LOG: execute <unnamed>: SET extra_float_digits = 3
LOG: execute <unnamed>: SELECT 2
LOG: execute <unnamed>: BEGIN
LOG: execute <unnamed>: SELECT picture.id, picture.filename, picture.name, picture.description, picture.role FROM picture WHERE picture.id=
DETAIL: parameters: = '2072'
LOG: execute S_1: ROLLBACK
为了确定:
解释分析 SELECT picture.id, picture.filename, picture.name, picture.description, picture.role FROM picture WHERE picture.id= 2072
给我:
Index Scan using picture_pkey on picture (cost=0.29..8.31 rows=1 width=46) (actual time=0.009..0.010 rows=1 loops=1)
Index Cond: (id = 2072)
Planning time: 0.043 ms
Execution time: 0.022 ms
符合预期。
万一有人关心,我发现了问题。
Torque 以 SimpleKey.keyFor 类型的 BigDecimal 值结束。这会导致问题,因为 Postgresql 在执行 select 时最终不会使用其索引。 (我猜是类型转换问题)。
我在扭矩方面遇到了一个非常奇怪的性能问题。看看下面的循环。 运行 需要 13 秒。
但是如果我替换这条线 c.and(PicturePeer.ID,SimpleKey.keyFor(2072));
和
c.and(PicturePeer.ID,2072);
相同的循环 运行s 在 0.2 秒内。这没有意义,因为它是完全相同的操作,即获取 id=2072;
的图片我什至在我的 PostgreSQL 数据库上启用了完整的查询日志,并且当我更改我使用的 2 个 c.add 方法中的哪一个时,对数据库的 select 查询不会改变。所以我不明白为什么没有 SimpleKey 的第二个解决方案比第一个快 50 倍。
我发现的原因是 c.and(PicturePeer.ID,SimpleKey.keyFor(2072)) 是 retrieveByPK 使用的方法,它会破坏我的性能。
con = Transaction.begin();
long start=System.currentTimeMillis();
for(int i=0;i!=1000;i++) {
Criteria c=new Criteria();
c=new Criteria();
c.and(PicturePeer.ID,SimpleKey.keyFor(2072));
// c.and(PicturePeer.ID,2072);
PicturePeer.doSelect(c,con);
}
long end=System.currentTimeMillis();
long diff=end-start;
System.out.println("Load diff=" + diff);
con.rollback();
来自 schema.xml 的图片关系如下所示:
<table name="picture" idMethod="native">
<column name="id" primaryKey="true" required="true" type="INTEGER"/>
<column name="filename" required="true" type="VARCHAR"/>
<column name="name" required="true" type="VARCHAR"/>
<column name="description" required="true" type="VARCHAR"/>
<column name="role" required="true" type="VARCHAR"/>
</table>
如果我在标准上调用 setLimit(1),使用 SimpleKey 的慢速方法与快速方法一样快,所以看起来 postgresql 正在使用 table 扫描,这毫无意义大部头书。特别是因为没有限制的慢速和快速版本给出了完全相同的查询日志。
这是来自 postgresql 的完整日志。 (select 2 是验证连接的东西)。
LOG: execute <unnamed>: SET extra_float_digits = 3
LOG: execute <unnamed>: SET extra_float_digits = 3
LOG: execute <unnamed>: SELECT 2
LOG: execute <unnamed>: BEGIN
LOG: execute <unnamed>: SELECT picture.id, picture.filename, picture.name, picture.description, picture.role FROM picture WHERE picture.id=
DETAIL: parameters: = '2072'
LOG: execute S_1: ROLLBACK
为了确定:
解释分析 SELECT picture.id, picture.filename, picture.name, picture.description, picture.role FROM picture WHERE picture.id= 2072
给我:
Index Scan using picture_pkey on picture (cost=0.29..8.31 rows=1 width=46) (actual time=0.009..0.010 rows=1 loops=1)
Index Cond: (id = 2072)
Planning time: 0.043 ms
Execution time: 0.022 ms
符合预期。
万一有人关心,我发现了问题。
Torque 以 SimpleKey.keyFor 类型的 BigDecimal 值结束。这会导致问题,因为 Postgresql 在执行 select 时最终不会使用其索引。 (我猜是类型转换问题)。