Iam*_*mIC 132 arrays postgresql indexing
我在文档中找不到这个问题的明确答案.如果列是数组类型,是否会对所有输入的值进行单独索引?
我创建了一个包含一int[]
列的简单表,并在其上放置了一个唯一索引.我注意到我无法添加相同的整数数组,这使我相信索引是数组项的组合,而不是每个项的索引.
INSERT INTO "Test"."Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test"."Test" VALUES ('{10, 20, 30}');
SELECT * FROM "Test"."Test" WHERE 20 = ANY ("Column1");
Run Code Online (Sandbox Code Playgroud)
索引是否有助于此查询?
Fra*_*ens 161
是的,您可以索引数组,但必须使用数组运算符和GIN索引类型.
例:
CREATE TABLE "Test"("Column1" int[]);
INSERT INTO "Test" VALUES ('{10, 15, 20}');
INSERT INTO "Test" VALUES ('{10, 20, 30}');
CREATE INDEX idx_test on "Test" USING GIN ("Column1");
-- To enforce index usage because we have only 2 records for this test...
SET enable_seqscan TO off;
EXPLAIN ANALYZE
SELECT * FROM "Test" WHERE "Column1" @> ARRAY[20];
Run Code Online (Sandbox Code Playgroud)
结果:
Bitmap Heap Scan on "Test" (cost=4.26..8.27 rows=1 width=32) (actual time=0.014..0.015 rows=2 loops=1)
Recheck Cond: ("Column1" @> '{20}'::integer[])
-> Bitmap Index Scan on idx_test (cost=0.00..4.26 rows=1 width=0) (actual time=0.009..0.009 rows=2 loops=1)
Index Cond: ("Column1" @> '{20}'::integer[])
Total runtime: 0.062 ms
Run Code Online (Sandbox Code Playgroud)
注意
似乎在许多情况下需要gin__int_ops选项
create index <index_name> on <table_name> using GIN (<column> gin__int_ops)
Run Code Online (Sandbox Code Playgroud)
我还没有看到过它可以在没有gin__int_ops选项的情况下使用&&和@>运算符
Erw*_*ter 84
@Tregoreg 在评论中向他提出的赏金提出了一个问题:
我没有找到目前的答案.在数组类型列上使用GIN索引不会提高ANY()运算符的性能.真的没有解决方案吗?
@ Frank接受的答案告诉你使用数组运算符,这对于Postgres 11 来说仍然是正确的.手册:
... PostgreSQL的标准发行版包括一个数组的GIN运算符类,它支持使用这些运算符的索引查询:
Run Code Online (Sandbox Code Playgroud)<@ @> = &&
在Postgres中,索引绑定到运算符(为某些类型实现),而不是单独的数据类型或函数或其他任何类型.这是伯克利原设计Postgres的遗产,现在很难改变.它通常工作得很好.这是一个关于pgsql-bugs的线程,Tom Lane对此进行了评论.
一些PostGis 函数(比如ST_DWithin()
)似乎违反了这个原则,但事实并非如此.这些函数在内部重写以使用各自的运算符.
索引表达式必须位于运算符的左侧.对于大多数运算符(包括上述所有运算符),如果将索引表达式放在右侧,则查询计划程序可以通过翻转操作数来实现此目的 - 假定COMMUTATOR
已定义a.该ANY
构造可以与各种操作员组合使用,而不是操作员本身.当用作constant = ANY (array_expression)
仅支持数组元素的=
运算符的索引时,我们需要一个换向器.GIN索引已经完成.= ANY()
Postgres目前还不够聪明,无法从中获取GIN可索引表达式.对于初学者来说,constant = ANY (array_expression)
是不完全等同于array_expression @> ARRAY[constant]
.如果涉及任何NULL 元素,则数组运算符返回错误,而ANY
构造可以在任何一方处理NULL.数据类型不匹配会有不同的结果.
相关答案:
在使用没有值的integer
数组(int4
,not int2
或int8
)时NULL
(如您的示例所示)考虑附加模块intarray
,它提供专门的,更快的运算符和索引支持.看到:
至于UNIQUE
你的问题中没有答案的约束:这是用整个数组值的btree索引实现的(就像你怀疑的那样)并且根本没有帮助搜索元素.细节:
Ed4*_*Ed4 36
现在可以索引各个数组元素.例如:
CREATE TABLE test (foo int[]);
INSERT INTO test VALUES ('{1,2,3}');
INSERT INTO test VALUES ('{4,5,6}');
CREATE INDEX test_index on test ((foo[1]));
SET enable_seqscan TO off;
EXPLAIN ANALYZE SELECT * from test WHERE foo[1]=1;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Scan using test_index on test (cost=0.00..8.27 rows=1 width=32) (actual time=0.070..0.071 rows=1 loops=1)
Index Cond: (foo[1] = 1)
Total runtime: 0.112 ms
(3 rows)
Run Code Online (Sandbox Code Playgroud)
这至少适用于Postgres 9.2.1.请注意,您需要为每个数组索引构建一个单独的索引,在我的示例中,我仅索引第一个元素.
归档时间: |
|
查看次数: |
69081 次 |
最近记录: |