是否可以在 Postgres 索引中混合使用 btree 和 gist?
Is it possible to mix btree and gist in a Postgres index?
我有一个 table 是这样构建的:
create table pois (
id varchar(32) primary key,
location geography(Point,4326),
category varchar(32),
entity_class varchar(1),
hide boolean
);
大多数查询看起来像这样:
SELECT * from pois
WHERE ( (
ST_contains(st_buffer(ST_SetSRID(ST_LineFromEncodedPolyline('ifp_Ik_vpAfj~FrehHhtxAhdaDpxbCnoa@~g|Ay_['), 4326)::geography, 5000)::geometry, location::geometry)
AND ST_Distance(location, ST_LineFromEncodedPolyline('ifp_Ik_vpAfj~FrehHhtxAhdaDpxbCnoa@~g|Ay_[')) < 5000
AND hide = false
AND entity_class in ('A', 'B')
) );
目前我有两个索引。一个在位置 "pois_location_idx" gist (location)
,一个在隐藏和 entity_class:"pois_select_idx" btree (hide, entity_class)
性能是可接受的table,但我想知道是否有更好的索引策略,特别是混合 btree + gist 索引是否可能并且有意义。
您可以使用 btree_gist
扩展中的运算符 类 来创建多列 GiST 索引:
CREATE EXTENSION btree_gist;
CREATE INDEX ON pois USING gist (location, category);
在你的特殊情况下,我会怀疑它的用处,因为 hide
是一个 boolean
而 GiST 索引不能支持 IN
子句。
也许创建一个部分索引会更好:
CREATE INDEX ON pois USING gist (location) WHERE NOT hide AND entity_class in ('A', 'B');
这样的索引只能用于WHERE
子句与索引匹配的查询,因此不太普遍。
我有一个 table 是这样构建的:
create table pois (
id varchar(32) primary key,
location geography(Point,4326),
category varchar(32),
entity_class varchar(1),
hide boolean
);
大多数查询看起来像这样:
SELECT * from pois
WHERE ( (
ST_contains(st_buffer(ST_SetSRID(ST_LineFromEncodedPolyline('ifp_Ik_vpAfj~FrehHhtxAhdaDpxbCnoa@~g|Ay_['), 4326)::geography, 5000)::geometry, location::geometry)
AND ST_Distance(location, ST_LineFromEncodedPolyline('ifp_Ik_vpAfj~FrehHhtxAhdaDpxbCnoa@~g|Ay_[')) < 5000
AND hide = false
AND entity_class in ('A', 'B')
) );
目前我有两个索引。一个在位置 "pois_location_idx" gist (location)
,一个在隐藏和 entity_class:"pois_select_idx" btree (hide, entity_class)
性能是可接受的table,但我想知道是否有更好的索引策略,特别是混合 btree + gist 索引是否可能并且有意义。
您可以使用 btree_gist
扩展中的运算符 类 来创建多列 GiST 索引:
CREATE EXTENSION btree_gist;
CREATE INDEX ON pois USING gist (location, category);
在你的特殊情况下,我会怀疑它的用处,因为 hide
是一个 boolean
而 GiST 索引不能支持 IN
子句。
也许创建一个部分索引会更好:
CREATE INDEX ON pois USING gist (location) WHERE NOT hide AND entity_class in ('A', 'B');
这样的索引只能用于WHERE
子句与索引匹配的查询,因此不太普遍。