My situation is somewhat similar to this earlier question: In PostgreSQL I have one table containing point geometries (P), and another containing polygons (G). I would like to join on the geometry field, e.g.
SELECT P.ID, G.SHAPE FROM POINTS P JOIN NL_1KM G ON ST_CONTAINS(G.SHAPE, P.SHAPE) The difference is that my polygons are a rectangular 1×1 km grid, so I don't think ST_Subdivide will help.
The grid table has ~126,000 records, and there are currently ~280 points. Both tables have a spatial index, all geometries are WGS84.
I would think that only 280 lookups on the grid would be required, but this takes roughly one minute. The same query with a 10km grid (1350 records) takes only 0.6 seconds
This is the query plan for the 1km grid:
QUERY PLAN Nested Loop (cost=0.00..9816799.62 rows=12459941 width=600) (actual time=2964.853..66014.294 rows=284 loops=1) Output: w.id, g.shape Join Filter: st_contains(g.shape, (w.shape)::st_geometry) Rows Removed by Join Filter: 37505400 -> Seq Scan on myschema.nl_1km g (cost=0.00..4571.58 rows=125858 width=596) (actual time=0.025..41.477 rows=125858 loops=1) Output: g.objectid, g.cellcode, g.eoforigin, g.noforigin, g.shape -> Materialize (cost=0.00..24.45 rows=297 width=484) (actual time=0.000..0.012 rows=298 loops=125858) Output: w.id, w.shape -> Seq Scan on myschema.points w (cost=0.00..22.97 rows=297 width=484) (actual time=0.007..0.106 rows=298 loops=1) Output: w.id, w.shape Planning Time: 0.293 ms Execution Time: 66014.393 ms Note that the st_geometry data type in the execution plan is an ArcGIS data type.
What am I missing?
Update, a few minutes after I posted...
One thing I was missing is that using ST_Intersects instead of ST_Contains makes things so fast, it almost scares me (0.06 sec). The new query plan shows that the spatial index on the grid is now used. So, my question should have been, why does ST_Contains not use the spatial index? If anyone has an answer to that?