[postgis-users] ST_Crosses doesn't use index?
Stefan Keller
sfkeller at gmail.com
Thu Feb 16 16:46:31 PST 2012
2012/2/17 Greg Williamson <gwilliamson39 at yahoo.com>:
> You might provide a description of the tables (\d xxxx at the psql prompt),
> and perhaps the output of an "EXPLAIN ANALYZE" for this command.
> Any non-standard config settings might be of relevance as well.
>
> Greg Williamson
>
Ok; I realize that my first query was taking whole DB whereas the
second takes a spatial subset.
But what I still wonder is, why ST_Contains needs to be applied to the
second geometry (of table b) too since the index should really sort
out any outliers of table b
See below (I'm using PostGIS 1.5 on Linux).
Yours, Stefan
Table def.:
CREATE TABLE osm_line
(
osm_id integer,
...
... -- around 20 attributes from osm2pgsql import
...
tags hstore,
way geometry
) WITH (OIDS=FALSE);
Query 1:
gisdb=> EXPLAIN ANALYZE
gisdb-> SELECT a.name
gisdb-> FROM osm_line a, osm_line b
gisdb-> WHERE ST_Contains(ST_Transform(ST_SetSRID('BOX(8.775 47.245,
8.873 47.208)'::box2d, 4326),900913),a.way)
gisdb-> AND a.osm_id != b.osm_id
gisdb-> AND ST_Crosses(a.way, b.way);
QUERY PLAN
----------
Nested Loop (cost=60.59..14659.13 rows=713 width=14) (actual
time=157.097..26896.760 rows=954 loops=1)
Join Filter: ((a.osm_id <> b.osm_id) AND _st_crosses(a.way, b.way))
-> Bitmap Heap Scan on osm_line a (cost=60.59..5708.36 rows=535
width=1097) (actual time=1.398..16.426 rows=1702 loops=1)
Recheck Cond: ('01030...'::geometry && way)
Filter: _st_contains('01030...'::geometry, way)
-> Bitmap Index Scan on osm_line_index (cost=0.00..60.46
rows=1606 width=0) (actual time=1.255..1.255 rows=1849 loops=1)
Index Cond: ('01030...'::geometry && way)
-> Index Scan using osm_line_index on osm_line b
(cost=0.00..15.94 rows=3 width=1083) (actual time=0.036..0.420 rows=28
loops=1702)
Index Cond: (a.way && b.way)
Total runtime: 26897.124 ms
(10 rows)
Query 2:
gisdb=> EXPLAIN ANALYZE
gisdb-> SELECT a.name
gisdb-> FROM osm_line a, osm_line b
gisdb-> WHERE ST_Contains(ST_Transform(ST_SetSRID('BOX(8.775 47.245,
8.873 47.208)'::box2d, 4326),900913),a.way)
gisdb-> AND ST_Contains(ST_Transform(ST_SetSRID('BOX(8.775 47.245,
8.873 47.208)'::box2d, 4326),900913),b.way)
gisdb-> AND a.osm_id != b.osm_id
gisdb-> AND ST_Crosses(a.way, b.way);
QUERY PLAN
----------
Nested Loop (cost=60.59..10353.28 rows=1 width=14) (actual
time=19.925..3088.990 rows=586 loops=1)
Join Filter: ((a.osm_id <> b.osm_id) AND _st_crosses(a.way, b.way))
-> Bitmap Heap Scan on osm_line a (cost=60.59..5708.36 rows=535
width=1097) (actual time=1.432..12.943 rows=1702 loops=1)
Recheck Cond: ('01030...'::geometry && way)
Filter: _st_contains('01030...'::geometry, way)
-> Bitmap Index Scan on osm_line_index (cost=0.00..60.46
rows=1606 width=0) (actual time=1.285..1.285 rows=1849 loops=1)
Index Cond: ('01030...'::geometry && way)
-> Index Scan using osm_line_index on osm_line b (cost=0.00..8.42
rows=1 width=1083) (actual time=0.464..1.069 rows=12 loops=1702)
Index Cond: (('01030...'::geometry && b.way)
AND (a.way && b.way))
Filter: _st_contains('01030...'::geometry, b.way)
Total runtime: 3089.228 ms
(11 rows)
gisdb=>
More information about the postgis-users
mailing list