【问题标题】:Why my postgis not use index on geometry field?为什么我的 postgis 不在几何字段上使用索引?
【发布时间】:2016-12-22 10:36:28
【问题描述】:

windows 上的 postgresql 9.5 + postgis 2.2。 我首先创建一个表:

CREATE TABLE points (
  id   SERIAL,
  ad   CHAR(40),
  name VARCHAR(200)
);

然后,添加几何字段“geom”:

select addgeometrycolumn('points', 'geom', 4326, 'POINT', 2);

并在其上创建要点索引:

CREATE INDEX points_index_geom ON points USING GIST (geom);

然后,我在表格中插入大约 1,000,000 个点。

我想查询距给定点给定距离内的所有点。 这是我的 sql 代码:

SELECT st_astext(geom) as location FROM points
WHERE st_distance_sphere(
     st_geomfromtext('POINT(121.33 31.55)', 4326),
     geom) < 6000;

结果是我想要的,但是太慢了。 当我在此代码上explain analyze verbose 时,我发现它不使用 points_index_geom(解释显示 seq 扫描并且没有索引)。

所以我想知道为什么它不使用索引,我应该如何改进?

【问题讨论】:

    标签: postgresql indexing postgis


    【解决方案1】:

    您不能指望ST_Distance_Sphere() 在此查询中使用索引。您正在对 geom 字段的内容进行计算,然后对计算结果进行比较。在这种情况下,数据库可能不会使用索引,除非您的函数索引与查询中的计算几乎相同。

    在给定距离内查找位置的正确方法是使用ST_DWithin

    ST_DWithin — 如果几何在指定范围内,则返回 true 彼此的距离。因为几何单位是空间单位 参考和对于地理单位是米,测量是 默认为 use_spheroid=true (围绕球体测量),更快 检查,use_spheroid=false 沿球体测量。

    此函数调用将自动包含一个边界框 将使用任何可用的索引进行比较 几何形状。

    【讨论】:

    • 我尝试了 st_dwithin(),我的源数据是由(经度,纬度)表示的许多点,我使用几何(点,4326)作为我的几何字段。然后,我的 sql 代码是 :SELECT id, name, st_astext(geom) from geom_points where st_dwithin(geom, st_geomfromtext('POINT(121.33 31.55)', 4326), 6000);但它也不在 geom 上使用 gist 索引。
    • 另一个问题是,如果我的给定距离使用米作为单位(不是几何单位),我可以使用几何类型吗?
    • 在您的查询中不是 6000 实际上是 6000 度,因为您使用的是 geom。因此,数据库不应该使用索引也是正确的。它需要找到每一件事
    • 我在您的第二条评论通过之前写下了我的上述评论。大约 1 度 = 111 公里
    • 非常感谢。最后我选择 GEOGRAPHY 以便我可以使用米(不是度数)作为距离。地理类型上的函数(st_DWithin,st_Covers ...)确实使用地理字段上的索引
    猜你喜欢
    • 2023-03-11
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2018-02-09
    • 2015-10-18
    相关资源
    最近更新 更多