postgresql中的IN子句可以使用多少个参数?

时间:2014-09-15 12:57:01

标签: java database postgresql jdbc

我在java程序中在postgresql数据库中执行查询,查询如下:

SELECT ... FROM table_name WHERE column_name IN("<list of values>");

问题是值列表是动态创建的,其大小没有限制,当此列表变得太大时,我收到PSQLException并显示消息:超出堆栈深度。 我的问题是如何确定在此异常发生之前我可以使用IN子句多少个参数?让我们说max_stack_depth是2MB,我可以用它来确定我可以用IN子句多少个参数吗?

3 个答案:

答案 0 :(得分:4)

inner joinvalues表格

select ...
from
    table_name
    inner join
    (values
        (first_value), (second_value)
    ) s(column_name) using (column_name)
;

或者,更容易将字符串构建到unnested数组

select ...
from
    table_name
    inner join
    unnest(
        array[first_value, second_value]
    ) s(column_name) using (column_name)
;

答案 1 :(得分:2)

如果您使用的是7.4或更早版本,则取决于max_expr_depth设置(或者我认为较新的max_stack_depth)。

您可以随时查看它的值:

test=> SHOW max_expr_depth;

并改变

test=> SET max_expr_depth TO 10;

然后你可以操作这个值。

Found HERE

  

对于任何普通查询,默认值10000都足够高,但是   如果需要你可以提高它。 (但如果你把它提高得太高,你就跑了   堆栈溢出导致服务器崩溃的风险。)

这不是解决问题的最佳解决方案,但我相信它会回答您的问题。

答案 2 :(得分:1)

如果您担心in子句中可能存在大量值,则可以使用临时表。

您创建一个临时表,其中包含一列和该列的索引。在查询之前,您将in子句的数据作为临时表中的行。然后使用以下结构之一执行查询:

SELECT * FROM table_name WHERE column_name in (SELECT column_name FROM temptable);
SELECT * FROM table_name a JOIN temptable b ON (a.column_name = b.column_name);
SELECT * FROM table_name a WHERE EXISTS (SELECT * FROM temptable t WHERE a.column_name=t.column_name);

并行运行查询不会有问题:一个会话写入的临时表中的内容对任何其他会话都是不可见的。

这种方法的最大优点是,SQL解析不必生成所有值。查询的结构保持不变,您甚至可以使用预准备语句。这与索引的使用一起可以带来巨大的性能提升。