重写大型IN子句的最佳性能是什么?

Jay*_*ane 3 sql postgresql go sql-in go-gorm

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

我只是IN在使用聚合时达到了条件的参数限制.示例查询:

SELECT SUM(total_amount) from Table where user_id in(...70k parameters) group by user_id
Run Code Online (Sandbox Code Playgroud)

我当前的一个边缘案例有> 65535个用户ID,所以我的Postgres客户端抛出一个错误:

got 66037 parameters but PostgreSQL only supports 65535 parameters
Run Code Online (Sandbox Code Playgroud)

我不确定最好的办法是什么.一个将处理此边缘情况的大量参数,同时不影响我的典型用例.我是否对id进行分块并迭代多次查询将其存储在内存中,直到我拥有所需的所有数据?用ANY(VALUES)...

显然,从查询中我对Postgres的知识非常有限,所以任何帮助都会令人难以置信地受到赞赏.

Erw*_*ter 7

你可以user_id IN (value [, ...])用以下之一替换:

user_id IN (subquery)
user_id = ANY (subquery)
user_id = ANY (array expression)
Run Code Online (Sandbox Code Playgroud)

子查询和数组都没有表现出相同的限制.最短的输入语法是:

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

详细信息和更多选项:

或者您可以创建一个(临时)表tmp_usr(user_id int),导入到它,可能使用SQL COPY或psql,\copy而不是INSERT为了获得具有非常大的集合的最佳性能,然后加入到表中,如:

SELECT SUM(total_amount)
FROM   tbl
JOIN   tmp_usr USING (user_id)
GROUP  BY user_id;
Run Code Online (Sandbox Code Playgroud)

BTW,GROUP BY user_id不包括user_idSELECT列表中看起来很可疑.可能是一个简化的示例查询.

  • 加入值子句而不是"IN"是另一种选择,有时也会更快.参见[这里](/sf/ask/3667118731/) (2认同)