重写大IN子句的最有效方法是什么?

时间:2018-10-09 01:12:37

标签: sql postgresql go go-gorm sql-in

我使用go and gorm编写了一个API,该API在我们的数据库上运行计算并返回结果。

使用汇总时,我刚达到IN条件的参数限制。查询示例:

SELECT SUM(total_amount) from Table where user_id in(...70k parameters) group by user_id

我当前的一个极端案例有> 65535个用户ID,因此我的Postgres客户端抛出错误:

got 66037 parameters but PostgreSQL only supports 65535 parameters

我不确定解决此问题的最佳方法是什么。在不影响我的典型用例的情况下,可以处理大量这种情况的参数。我是否会对ID进行分块并遍历存储在内存中的多个查询,直到获得所需的所有数据为止?使用ANY(VALUES) ...

很明显,从查询中我对Postgres的了解非常有限,因此非常感谢您的帮助。

1 个答案:

答案 0 :(得分:7)

您可以将user_id IN (value [, ...])替换为以下其中一项:

user_id IN (subquery)
user_id = ANY (subquery)
user_id = ANY (array expression)

子查询和数组都没有相同的限制。最短的输入语法为:

user_id = ANY ('{1,2,3}'::int[])  -- make array type match type of user_id

详细信息和更多选项:

或者,您可以创建一个(临时)表tmp_usr(user_id int),然后使用SQL COPY或psql \copy而不是{{1} },以使非常大的设置获得最佳性能,然后 join 到表中,例如:

INSERT

顺便说一句,SELECT SUM(total_amount) FROM tbl JOIN tmp_usr USING (user_id) GROUP BY user_id; GROUP BY user_id列表中未包含user_id的情况看起来很可疑。可能是简化的示例查询。