Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgreSQL-最大参数数在“中”;在;条款_Postgresql - Fatal编程技术网

PostgreSQL-最大参数数在“中”;在;条款

PostgreSQL-最大参数数在“中”;在;条款,postgresql,Postgresql,在Postgres中,可以指定In子句,如下所示: SELECT * FROM user WHERE id IN (1000, 1001, 1002) 有人知道你可以通过的参数的最大数量吗?< P>你可能想考虑重构这个查询,而不是添加一个任意长的IDS列表…如果ID确实遵循示例中的模式,则可以使用范围: SELECT * FROM user WHERE id >= minValue AND id <= maxValue; 根据位于PostgreSQL的源代码,PostgreSQL

在Postgres中,可以指定In子句,如下所示:

SELECT * FROM user WHERE id IN (1000, 1001, 1002)

有人知道你可以通过的参数的最大数量吗?

< P>你可能想考虑重构这个查询,而不是添加一个任意长的IDS列表…如果ID确实遵循示例中的模式,则可以使用范围:

SELECT * FROM user WHERE id >= minValue AND id <= maxValue;

根据位于PostgreSQL的源代码,PostgreSQL没有明确限制参数的数量

以下是第870行的代码注释:

/*
 * We try to generate a ScalarArrayOpExpr from IN/NOT IN, but this is only
 * possible if the inputs are all scalars (no RowExprs) and there is a
 * suitable array type available.  If not, we fall back to a boolean
 * condition tree with multiple copies of the lefthand expression.
 * Also, any IN-list items that contain Vars are handled as separate
 * boolean conditions, because that gives the planner more scope for
 * optimization on such clauses.
 *
 * First step: transform all the inputs, and detect whether any are
 * RowExprs or contain Vars.
 */

在子句中传递给的元素数量没有限制。如果有更多的元素,它会把它看作数组,然后对于数据库中的每个扫描,它将检查它是否包含在数组中。这种方法没有那么好的可扩展性。不要使用IN子句,而是尝试使用带临时表的内部联接。有关更多信息,请参阅。使用内部连接比例以及查询优化器可以利用哈希连接和其他优化。而对于IN子句,优化器无法优化查询。我注意到这一变化至少加速了2倍

如果您有如下查询:

SELECT * FROM user WHERE id IN (1, 2, 3, 4 -- and thousands of another keys)
SELECT * FROM user WHERE id = ANY(VALUES (1), (2), (3), (4) -- and thousands of another keys)
如果重写查询,您可能会提高性能,如:

SELECT * FROM user WHERE id IN (1, 2, 3, 4 -- and thousands of another keys)
SELECT * FROM user WHERE id = ANY(VALUES (1), (2), (3), (4) -- and thousands of another keys)
查询计划 但如果尝试第二个查询:

explain select * from test where id = any (values (1), (2));
查询计划
我们可以看到,postgres构建临时表并与之连接这并不是对当前问题的真正回答,但也可能对其他人有所帮助

至少我可以看出,使用Posgresql的JDBC驱动程序9.1,可以传递到PostgreSQL后端的技术限制是32767个值(=Short.MAX_值)

这是对postgresql jdbc驱动程序的“从x中删除id(…100k值…)”的测试:

Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 100000
    at org.postgresql.core.PGStream.SendInteger2(PGStream.java:201)

作为一个对Oracle DB更有经验的人,我也担心这个限制。我对一个查询进行了性能测试,该查询在-列表中的
中包含~10000个参数,通过实际将所有素数列为查询参数,从包含前100000个整数的表中获取最多100000个素数

我的结果表明,您不必担心查询计划优化器过载或在不使用索引的情况下获取计划,因为它会将查询转换为使用
=ANY({…}::integer[])
,从而可以按预期利用索引:

-- prepare statement, runs instantaneous:
PREPARE hugeplan (integer, integer, integer, ...) AS
SELECT *
FROM primes
WHERE n IN ($1, $2, $3, ..., $9592);

-- fetch the prime numbers:
EXECUTE hugeplan(2, 3, 5, ..., 99991);

-- EXPLAIN ANALYZE output for the EXECUTE:
"Index Scan using n_idx on primes  (cost=0.42..9750.77 rows=9592 width=5) (actual time=0.024..15.268 rows=9592 loops=1)"
"  Index Cond: (n = ANY ('{2,3,5,7, (...)"
"Execution time: 16.063 ms"

-- setup, should you care:
CREATE TABLE public.primes
(
  n integer NOT NULL,
  prime boolean,
  CONSTRAINT n_idx PRIMARY KEY (n)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.primes
  OWNER TO postgres;

INSERT INTO public.primes
SELECT generate_series(1,100000);

然而,这(相当陈旧)表明,在规划此类查询时仍有不可忽略的成本,所以请恕我直言。

刚刚尝试过。答案是->
超出范围的整数作为2字节值:32768

PostgreSQL的
EXPLAIN
说它在(…)
as
ANY(“{…}”)::integer[])
。无论如何,@KiranJonnalagadda提高了性能(也许可以忽略不计)如果不需要内部工作的话。但是我听说博士后-9.3+的表现似乎是一样的。您所指的链接没有说明它在谈论什么DBMS。虽然我可以确认,在Oracle DB上,由于解析和规划此类查询的开销很大,使用临时表比在子句中使用组合
的查询提供了巨大的性能提升,但我无法确认Postgres 9.5的问题,请参见。OP询问了DB引擎的限制,但是为了寻找JDBC的局限性,我来到这里,这就是我想要的。所以有一个限制,但是,相当高。
Caused by: java.io.IOException: Tried to send an out-of-range integer as a 2-byte value: 100000
    at org.postgresql.core.PGStream.SendInteger2(PGStream.java:201)
-- prepare statement, runs instantaneous:
PREPARE hugeplan (integer, integer, integer, ...) AS
SELECT *
FROM primes
WHERE n IN ($1, $2, $3, ..., $9592);

-- fetch the prime numbers:
EXECUTE hugeplan(2, 3, 5, ..., 99991);

-- EXPLAIN ANALYZE output for the EXECUTE:
"Index Scan using n_idx on primes  (cost=0.42..9750.77 rows=9592 width=5) (actual time=0.024..15.268 rows=9592 loops=1)"
"  Index Cond: (n = ANY ('{2,3,5,7, (...)"
"Execution time: 16.063 ms"

-- setup, should you care:
CREATE TABLE public.primes
(
  n integer NOT NULL,
  prime boolean,
  CONSTRAINT n_idx PRIMARY KEY (n)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.primes
  OWNER TO postgres;

INSERT INTO public.primes
SELECT generate_series(1,100000);