我从java程序在postgresql数据库中执行一个查询,查询如下:
SELECT ... FROM table_name WHERE column_name IN("<list of values>");问题是,值列表是动态创建的,其大小没有限制,当这个列表变得太大时,我将得到一个PSQLException,消息是:堆栈深度长度超过了。我的问题是,在这种异常发生之前,如何确定在IN子句中可以使用多少个参数?假设max_stack_depth是2MB,我可以用它来确定IN子句可以使用多少个参数吗?
发布于 2014-09-15 13:22:24
对inner join表执行values
select ...
from
table_name
inner join
(values
(first_value), (second_value)
) s(column_name) using (column_name)
;或者,更容易构建字符串,到未嵌套的数组。
select ...
from
table_name
inner join
unnest(
array[first_value, second_value]
) s(column_name) using (column_name)
;发布于 2014-09-15 13:27:31
如果您使用的是7.4或更早版本,则取决于max_expr_depth设置(或更新的max_stack_depth )。
您可以始终检查它的价值:
test=> SHOW max_expr_depth;和变化
test=> SET max_expr_depth TO 10;然后您可以对此值进行操作。
在这里发现的
对于任何正常的查询,默认值10000都足够高,但如果需要,可以将其提高。(但如果将其抬高过高,则会因堆栈溢出而导致服务器崩溃。)
这不是解决你问题的最好办法,但我相信它能回答你的问题。
发布于 2014-09-15 13:34:10
当您担心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分析不必产生所有的值。查询的结构保持不变,甚至可以使用准备好的语句。这与索引的使用一起可以极大地提高性能。
https://stackoverflow.com/questions/25848652
复制相似问题