【问题标题】:Avoiding fetch in Jooq subquery避免在 Jooq 子查询中获取
【发布时间】:2019-12-21 09:27:16
【问题描述】:

我需要从一个非常大的表中选择一个“页面”数据。由于 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)));

附言我这样做的原因是由于大偏移量的 orderBy / offset / 限制(由于是 blob 类型,我选择的列之一不符合添加到索引的条件,因此我无法创建覆盖指数)。

【问题讨论】:

    标签: mysql jooq


    【解决方案1】:

    是的,确实可以避免单独的数据库往返。在您的情况下,您应该能够在第一个查询中简单地使用第二个查询的 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 的原因。

    【讨论】:

      猜你喜欢
      • 2016-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      • 2017-04-24
      • 1970-01-01
      相关资源
      最近更新 更多