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

What is the most performant way to rewrite a large IN clause?

我使用 go 和 gorm 写了一个 API,它在我们的数据库上运行计算并 returns 结果。

我在使用聚合时刚刚达到 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

详细信息和更多选项:

或者 你可以创建一个(临时的)table tmp_usr(user_id int),导入它,也许用 SQL COPY或 psql \copy 而不是 INSERT 以获得 非常大的集合 的最佳性能,然后 join 到 table喜欢:

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

顺便说一句,SELECT 列表中没有包含 user_idGROUP BY user_id 看起来很可疑。可能是一个简化的示例查询。