未使用数组列上的 GIN 索引,即使在将“enable_seqscan”设置为关闭之后?
GIN index on array column not used, even after setting `enable_seqscan` to off?
根据this评论的推荐,我建立了一个intarray GIN索引。我什至set local enable_seqscan = 'off';
。不过,当我 EXPLAIN
我的查询时,它正在进行顺序扫描。为了演示,我创建了一个名为 deletethis
.
的虚拟 table
devapp=>
devapp=> \d deletethis;
Table "public.deletethis"
Column | Type | Collation | Nullable | Default
--------+-----------+-----------+----------+---------
col1 | integer[] | | |
Indexes:
"deletethis_idx" gin (col1 gin__int_ops)
devapp=>
devapp=>
devapp=> BEGIN; set local enable_seqscan = False; SHOW enable_seqscan; EXPLAIN SELECT * from deletethis where 1 = ANY(col1); COMMIT;
BEGIN
SET
enable_seqscan
----------------
off
(1 row)
QUERY PLAN
-------------------------------------------------------------------------------
Seq Scan on deletethis (cost=10000000000.00..10000000040.60 rows=7 width=32)
Filter: (1 = ANY (col1))
(2 rows)
COMMIT
devapp=>
尽管 enable_seqscan
已设置为 off
为什么它仍在执行序列扫描而不使用索引?
正如我在您提到的同一问题的另一个答案中提到的,ANY
构造无法利用 GIN 索引:
- Can PostgreSQL index array columns?
这可以使用你的索引:
SELECT * FROM deletethis WHERE col1 @> '{1}';
'{1}'
作为 array literal. An array constructor (ARRAY[1]
) 或 integer[]
类型的任何变量或列也可以。
参见:
- Check if value exists in Postgres array
输入的显式类型转换是可选的,因为文字的赋值转换以及构造函数的默认类型恰好对我们有用。
但是在使用附加模块 intarray
的运算符 类 时,请注意使用 integer
(int4
) 进行操作,不要使用其他任何东西。相关:
- Compare arrays for equality, ignoring order of elements
根据this评论的推荐,我建立了一个intarray GIN索引。我什至set local enable_seqscan = 'off';
。不过,当我 EXPLAIN
我的查询时,它正在进行顺序扫描。为了演示,我创建了一个名为 deletethis
.
devapp=>
devapp=> \d deletethis;
Table "public.deletethis"
Column | Type | Collation | Nullable | Default
--------+-----------+-----------+----------+---------
col1 | integer[] | | |
Indexes:
"deletethis_idx" gin (col1 gin__int_ops)
devapp=>
devapp=>
devapp=> BEGIN; set local enable_seqscan = False; SHOW enable_seqscan; EXPLAIN SELECT * from deletethis where 1 = ANY(col1); COMMIT;
BEGIN
SET
enable_seqscan
----------------
off
(1 row)
QUERY PLAN
-------------------------------------------------------------------------------
Seq Scan on deletethis (cost=10000000000.00..10000000040.60 rows=7 width=32)
Filter: (1 = ANY (col1))
(2 rows)
COMMIT
devapp=>
尽管 enable_seqscan
已设置为 off
为什么它仍在执行序列扫描而不使用索引?
正如我在您提到的同一问题的另一个答案中提到的,ANY
构造无法利用 GIN 索引:
- Can PostgreSQL index array columns?
这可以使用你的索引:
SELECT * FROM deletethis WHERE col1 @> '{1}';
'{1}'
作为 array literal. An array constructor (ARRAY[1]
) 或 integer[]
类型的任何变量或列也可以。
参见:
- Check if value exists in Postgres array
输入的显式类型转换是可选的,因为文字的赋值转换以及构造函数的默认类型恰好对我们有用。
但是在使用附加模块 intarray
的运算符 类 时,请注意使用 integer
(int4
) 进行操作,不要使用其他任何东西。相关:
- Compare arrays for equality, ignoring order of elements