【问题标题】:How to make JOOQ to use arrays in the IN clause如何让 JOOQ 在 IN 子句中使用数组
【发布时间】:2017-08-23 06:41:00
【问题描述】:

我希望 JOOQ 生成 ... in (?) 并将列表绑定为数组参数 (Postgres)。我的代码看起来像

.where(
   Tables.TABLE.FIELD.in(idsList)
)
  1. 我该怎么做?
  2. 为什么默认不这样做,因为它更有效地生成(并由 PG 解析)字符串in (?, ?, ?, ?, ...)

【问题讨论】:

  • 看起来你可能只在in 子句中做了几个id,但如果你做了数百个,请考虑创建一个batch ids table。考虑一下,因为您永远不知道用户何时会实际选择数百个不同的项目(例如,想想 gmail 复选框)。

标签: java arrays postgresql jooq


【解决方案1】:

我该怎么做?

您可以使用DSL.any(T[]) 运算符,例如

TABLE.FIELD.eq(any(1, 2, 3))

这将只绑定一个数组变量到 JDBC 语句

为什么默认不这样做,因为它更有效地生成(并由 PG 解析)字符串

可能值得考虑Settings 中的标志。我已经为此注册了一个功能请求:https://github.com/jOOQ/jOOQ/issues/6029

一般来说,jOOQ 允许用户准确地编写他们想要发送到数据库服务器的 SQL,因此 SQL 的自动“优化”和重写对于某些用户来说可能会显得非常意外。这只是 jOOQ 中的一般经验法则。考虑优化并让他们通过Settings 选择加入总是值得的。

注意过早优化!

但是,实际衡量这些东西总是很重要的。虽然您建议的方法肯定会减少解析和 SQL 生成开销,但请注意,数组的基数可能比硬连线的IN 列表更难正确估计。将数组用于小列表可能会对您的执行计划产生负面影响。因此,您在解析器端节省的几微秒将与执行端的几毫秒 (?) 相权衡!

我在以下博客文章中对此进行了基准测试: https://blog.jooq.org/sql-in-predicate-with-in-list-or-with-array-which-is-faster/

IN 列表似乎一直优于数组版本(在我的特定基准案例中),直到长度约为 50

【讨论】:

  • 如果您将基准代码与结果一起发布也会有所帮助。 jOOQ 是否为此类基准提供任何支持?类似 jOOQ-JMH 的东西?
  • @DmitryGusev:添加了基准链接。它包含被基准测试的 SQL 查询,以及基准测试中使用的 Sakila 示例数据库的链接。 jOOQ-JMH 基准存根的有趣想法。我为此创建了一个功能请求:github.com/jOOQ/jOOQ/issues/6030.
  • 我在TABLE.FIELD.eq(DSL.any(1, 2, 3)) 收到no suitable method found for in(QuantifiedSelect<Record1<Long>>) 错误
  • 嗯,你正在传递整数,但你的方法期待长......如何传递 1L, 2L, 3L 代替?
  • 哦,是的,刚刚意识到应该是eq,而不是in。谢谢
猜你喜欢
  • 2021-08-28
  • 2021-09-25
  • 1970-01-01
  • 2016-05-07
  • 2018-06-08
  • 1970-01-01
  • 2021-12-21
  • 2021-09-19
  • 2016-11-07
相关资源
最近更新 更多