是否可以在 Postgres 索引中混合使用 btree 和 gist?

sim*_*one 2 postgresql indexing postgis

我有一个这样构建的表:

create table pois (
       id varchar(32) primary key,
       location geography(Point,4326),
       category varchar(32),
       entity_class varchar(1),
       hide boolean
);
Run Code Online (Sandbox Code Playgroud)

大多数查询如下所示:

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')
) );
Run Code Online (Sandbox Code Playgroud)

目前我有两个索引。一份关于位置"pois_location_idx" gist (location),一份关于隐藏和实体类:"pois_select_idx" btree (hide, entity_class)

性能是可以接受的,但我想知道是否有更好的索引策略,特别是混合 btree + gist 索引是否可能且有意义。

Lau*_*lbe 8

您可以使用扩展中的运算符类btree_gist来创建多列 GiST 索引:

CREATE EXTENSION btree_gist;

CREATE INDEX ON pois USING gist (location, category);
Run Code Online (Sandbox Code Playgroud)

在你的特殊情况下,我会怀疑它的用处,因为hideis aboolean并且 GiST 索引不能支持子句IN

也许创建部分索引会更好:

CREATE INDEX ON pois USING gist (location) WHERE NOT hide AND entity_class in ('A', 'B');
Run Code Online (Sandbox Code Playgroud)

这种索引只能用于WHERE子句与索引匹配的查询,因此不太通用。