避免在Jooq子查询中获取

时间:2019-08-14 19:52:59

标签: mysql jooq

我需要从一个很大的表中选择一个数据页面。由于WHERE子句以及需要分页到相当大的偏移量,因此我正在使用子查询来获取ID。仅当我在末尾加上fetch时,此策略才有效。 (我认为)这导致数据库的额外往返。有什么办法可以避免多余的fetch

final Object subquery =
    JooqUtil.DSL_CONTEXT
        .select(ID_FIELD)
        .from(MY_TABLE)
        .where(conditionBuilder.build())
        .orderBy(UPDATED_AT.asc())
        .offset(offset.get())
        .limit(limit.get())
        .fetch();

return JooqUtil.toPreparedSql(
    JooqUtil.DSL_CONTEXT
        .select(JooqUtil.createFields(ALL_COLUMN_NAMES))
        .from(MY_TABLE)
        .where(ID_FIELD.in(subquery)));

p.s。我这样做的原因是由于orderBy / offset /对大偏移量的限制(我选择的列之一由于是blob类型而不能添加到索引中,所以我无法创建覆盖指数)。

1 个答案:

答案 0 :(得分:2)

是的,确实可以避免单独的数据库往返。就您而言,您应该能够在第一个查询中简单地使用第二个查询的SELECT子句:

return JooqUtil.toPreparedSql(
    JooqUtil.DSL_CONTEXT
        .select(JooqUtil.createFields(ALL_COLUMN_NAMES))
        .from(MY_TABLE)
        .where(conditionBuilder.build())
        .orderBy(UPDATED_AT.asc())
        .offset(offset.get())
        .limit(limit.get())
);

由于行具有ID,但是您可能希望使用jOOQ的SEEK子句而不是OFFSET。我建议您阅读this blog postthis manual section,它们解释了区别和为什么要使用SEEK