PostgreSQL 中的 Gist 索引仅适用于顺序,但不适用于谓词

Gist index in PostgreSQL only works on order, but not on where predicate

我有一个带有 LatLon 的普通 table 列,其中包含一个对象位置在 space 中的点,并在 GiST 上创建了索引本栏目:

create table "Machine"
(
    "MachineId" integer not null,
    "Name" text,
    "Description" text default ''::text,
    "LatLon" point default point((0)::double precision, (0)::double precision) not null
);

create index on "Machine" using gist("LatLon");

我有一个关于只选择距离固定坐标点一定距离内的点的查询:

select * from "Machine" where "LatLon" <-> point(25.123456789,-60.123456789) < 100;

尽管对此类查询的解释显示在执行期间未使用索引:

Seq Scan on "Machine"  (cost=0.00..244762.46 rows=1753121 width=208)
  Filter: (("LatLon" <-> '(25.123456789,-60.123456789)'::point) < '100'::double precision)
  Rows Removed by Filter: 5259364

同时,对 LatLon 列执行规范 order by 查询显示索引完美运行:

select * from "Machine" order by "LatLon" <-> point(25.123456789,-60.123456789);
Index Scan using "Machine_LatLon_idx" on "Machine"  (cost=0.41..1021907.70 rows=5259364 width=216)
  Order By: ("LatLon" <-> '(25.123456789,-60.123456789)'::point)

为什么 GiST 索引不适用于带有距离运算符 <->where 语句?

因为有人实现了一个,而不是另一个。

请注意,这不仅仅是一个运算符,而且其他运算符对(<-><,此处)也没有使用索引。因此,您将不得不引入支持此类索引的基础架构以及此特定实现。

如果你只是想要有索引的接近的东西,你需要将距离拉入点以获得一个圆。然后你有一个很好的二元运算符来抓取索引:

select * from "Machine" where "LatLon" <@ circle(point(25.123456789,-60.123456789),100);