向标准添加简单键时,扭矩 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 时最终不会使用其索引。 (我猜是类型转换问题)。