【问题标题】:Prevent "order by" clause in Ebean防止 Ebean 中的“order by”子句
【发布时间】:2019-01-26 05:59:48
【问题描述】:

Ebean ORM 会在每个查询中添加sort by t0.id 子句,这会导致非常非常糟糕的性能。

我使用 Play Framework 2.6、H2 1.4 数据库和 Ebean 11.15 (PlayEbean 4.1.3)。我有一个有 100k 行的表,而且它越来越大。

我有几个计划任务,它们从表中选择一批记录并处理数据,顺序无关紧要。

所以例如我使用这个查询:

Chunk.find.query()
        .select("id, lat, lon, data, status")
        .fetch("area", "id, polygon")
        .setMaxRows(100)
        .where()
            .eq("status", 0)
        .query()
        .findList();

然后 Eben 生成并执行这个:

select 
  c.id,
  c.lat,
  c.lon,
  c.data,
  c.status,
  a.id,
  a.polygon
from chunk c
join area a on a.id = c.area_id 
where c.status = 0
order by c.id
limit 100;

如果没有order by c.id,那就太好了。

如果我手动执行查询,它将需要大约 5000 毫秒。但是如果我删除 order by 子句,它只需要大约 10 毫秒!而且我的应用程序中有很多地方不需要排序,它可以更快地工作。

【问题讨论】:

  • groups.google.com/forum/#!forum/ebean,尝试在这里发帖,这是与 ebean 相关的主要问题论坛,由 ebean 的开发人员监督。
  • 嗨@Aunmag,你进步了吗?
  • 嗨@rob-bygrave,是的。目前唯一的解决方案是添加.orderBy("status")
  • 为什么用 setMaxRows(100) 限制行数并且不想要任何排序?您想要随机的 100 行,还是希望 db 提供一些默认顺序?您会在某个时间检索具有 100 行的下一页吗?
  • findNative() 也可以。鉴于“从表中选择一批记录并处理数据的几个计划任务”......我几乎希望状态列上有一个“部分索引”,查询上有一个 updateSkipLocked()(取决于生产数据库正在使用)。

标签: java playframework ebean


【解决方案1】:

您可以将 .orderById(false) 与您正在使用的 Ebean 版本一起使用。这是在11.12.1 中添加的

Chunk.find.query()
    .select("id, lat, lon, data, status")
    .fetch("area", "id, polygon")
    .setMaxRows(100)
    .where()
        .eq("status", 0)
    .query()
    .orderById(false)
    .findList();

【讨论】:

  • 不幸的是该方法没有效果。我仍然在 SQL 日志中看到 ORDER BY id
【解决方案2】:

目前唯一的解决方案是使用.orderBy("1")

【讨论】:

    猜你喜欢
    • 2011-10-15
    • 2023-04-08
    • 2017-12-07
    • 2011-09-07
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    相关资源
    最近更新 更多