【问题标题】:How to create a spatial index on a PostgreSQL GEOMETRY field?如何在 PostgreSQL GEOMETRY 字段上创建空间索引?
【发布时间】:2021-08-20 14:32:24
【问题描述】:

我正在使用 PostgreSQL 和 PostGIS 来处理表格中的地理坐标。如何在GEOMETRY(POINT)类型字段上创建空间索引来提高基于距离的ST_DWithin查询的性能?

我正在使用迁移来创建索引。

【问题讨论】:

    标签: node.js postgresql sequelize.js postgis


    【解决方案1】:

    对于几何,建议使用gist 索引,例如

    CREATE INDEX idx_any_label ON mytable USING gist (geom_column);
    

    数据样本(50k 个随机点):

    CREATE TABLE t (geom geometry(point,4326));
    INSERT INTO t 
    SELECT ('SRID=4326;POINT('||floor(random() * 50)||' ' ||floor(random() * 50) ||')')
    FROM generate_series(1,50000);
    

    没有索引的查询计划:

    EXPLAIN ANALYSE
    SELECT * FROM t
    WHERE ST_DWithin('SRID=4326;POINT(1 1)',geom,1);
        
     Seq Scan on t  (cost=0.00..1252068.48 rows=5 width=32) (actual time=122.091..144.137 rows=98 loops=1)
       Filter: st_dwithin('0101000020E6100000000000000000F03F000000000000F03F'::geometry, geom, '1'::double precision)
       Rows Removed by Filter: 49902
     Planning Time: 0.083 ms
     JIT:
       Functions: 2
       Options: Inlining true, Optimization true, Expressions true, Deforming true
       Timing: Generation 0.387 ms, Inlining 83.228 ms, Optimization 30.947 ms, Emission 7.626 ms, Total 122.187 ms
     Execution Time: 186.107 ms
    

    带有要点索引的查询计划

    CREATE INDEX idx_t_geom ON t USING gist (geom);
    
    EXPLAIN ANALYSE
    SELECT * FROM t
    WHERE ST_DWithin('SRID=4326;POINT(1 1)',geom,1);
                                                               QUERY PLAN                                                           
    --------------------------------------------------------------------------------------------------------------------------------
     Bitmap Heap Scan on t  (cost=4.98..2119.16 rows=5 width=32) (actual time=0.086..0.367 rows=98 loops=1)
       Filter: st_dwithin('0101000020E6100000000000000000F03F000000000000F03F'::geometry, geom, '1'::double precision)
       Rows Removed by Filter: 83
       Heap Blocks: exact=139
       ->  Bitmap Index Scan on idx_t_geom  (cost=0.00..4.98 rows=77 width=0) (actual time=0.063..0.064 rows=181 loops=1)
             Index Cond: (geom && st_expand('0101000020E6100000000000000000F03F000000000000F03F'::geometry, '1'::double precision))
     Planning Time: 0.291 ms
     Execution Time: 2.237 ms
    

    演示:db<>fiddle

    【讨论】:

    • 有没有办法在不执行原始 SQL 命令的情况下创建这个索引?任何续集功能?
    • 我对 sequelize 不是很熟悉,但我很确定可以执行 ddl 语句,例如创建索引。你不能直接在数据库中自己运行这个 stamentet 吗?它真的很短,只需触发一次。
    猜你喜欢
    • 2012-09-06
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-12
    • 2015-06-27
    • 1970-01-01
    • 2018-06-25
    • 2016-10-02
    相关资源
    最近更新 更多