[PostGIS] #5984: PostGIS selectivity is screwing up queries and forcing it to choose a spatial index when it's inappropriate
PostGIS
trac at osgeo.org
Wed Sep 10 14:34:13 PDT 2025
#5984: PostGIS selectivity is screwing up queries and forcing it to choose a
spatial index when it's inappropriate
----------------------+---------------------------
Reporter: robe | Owner: pramsey
Type: defect | Status: new
Priority: critical | Milestone: PostGIS 3.4.5
Component: postgis | Version: 3.5.x
Keywords: |
----------------------+---------------------------
Issue discussed in:
https://lists.osgeo.org/pipermail/postgis-users/2025-September/046864.html
Paul suggested reverting the operator introduced in [31bcb7d414/git]
```
ALTER OPERATOR @ (geometry , geometry)
SET ( RESTRICT = contsel,
JOIN = contjoinsel )
;
```
and that does indeed return to the old 3.3 behavior for this query:
```
EXPLAIN (ANALYZE, BUFFERS) SELECT wn.way_id FROM way_nodes AS wn, nodes AS
n WHERE wn.node_id = 8646506472 AND wn.node_id = n.id AND
ST_Contains(ST_GeomFromEWKT('SRID=4326;POLYGON((6.1198199
52.612195500000006,6.1198199 53.2038323,7.0927397 53.2038323,7.0927397
52.612195500000006,6.1198199 52.612195500000006))'), n.geom);
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nested Loop (cost=0.99..29.54 rows=1 width=8) (actual
time=5648.531..5648.532 rows=0 loops=1)
Buffers: shared hit=6744524 read=845409 written=5
-> Index Scan using idx_way_nodes_node_id on way_nodes wn
(cost=0.57..8.59 rows=1 width=16) (actual time=0.021..0.022 rows=1
loops=1)
Index Cond: (node_id = '8646506472'::bigint)
Buffers: shared read=5
-> Index Scan using idx_nodes_geom on nodes n (cost=0.42..20.94
rows=1 width=8) (actual time=5648.507..5648.507 rows=0 loops=1)
Index Cond: (geom @
'0103000020E61000000100000005000000D5A35F11B27A184013A1116C5C4E4A40D5A35F11B27A18402A2F432D179A4A40D529EA27F75E1C402A2F432D179A4A40D529EA27F75E1C4013A1116C5C4E4A40D5A35F11B27A184013A1116C5C4E4A40'::geometry)
Filter: ((id = '8646506472'::bigint) AND
st_contains('0103000020E61000000100000005000000D5A35F11B27A184013A1116C5C4E4A40D5A35F11B27A18402A2F432D179A4A40D529EA27F75E1C402A2F432D179A4A40D529EA27F75E1C4013A1116C5C4E4A40D5A35F11B27A184013A1116C5C4E4A40'::geometry,
geom))
Rows Removed by Filter: 9886042
Buffers: shared hit=6744524 read=845404 written=5
Planning:
Buffers: shared hit=11 read=15
Planning Time: 0.294 ms
Execution Time: 5648.551 ms
(14 rows)
```
Note the polygon in question covers a good chunk of the table as is
somewhat obvious from the 9886042 records that needed to be used by a
filter,
compared to same query on a 3.3 instance which doesn't use the spatial
index at all and thus has only one row to remove using Filter.
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5984>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list