重写大型 IN 子句的最高性能方法是什么?



我使用 go 和 gorm 编写了一个 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的了解非常有限,因此任何帮助将不胜感激。

您可以将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

详细信息和更多选项:

  • 如何在 WHERE 子句中使用 ANY 而不是 in?

或者,您可以创建一个(临时(表tmp_usr(user_id int),导入到其中,也许使用 SQLCOPY或 psqlcopy而不是INSERT以获得大型集的最佳性能,然后连接到表,如下所示:

SELECT user_id, SUM(total_amount)
FROM   tbl
JOIN   tmp_usr USING (user_id)
GROUP  BY user_id;

顺便说一句,您需要在SELECT列表中包含user_id以识别总和。

最新更新