[postgis-tickets] [PostGIS] #3739: ST_Within Not using index

PostGIS trac at osgeo.org
Wed Apr 26 16:11:45 PDT 2017


#3739: ST_Within Not using index
--------------------------+---------------------------
  Reporter:  postgispaul  |      Owner:  pramsey
      Type:  defect       |     Status:  new
  Priority:  medium       |  Milestone:  PostGIS 2.3.3
 Component:  postgis      |    Version:  2.3.x
Resolution:               |   Keywords:
--------------------------+---------------------------

Comment (by robe):

 Well bitmap/normal index is not an issue.  Usually in my case the bitmap
 and index scan speeds are pretty close and the bitmap often beats out the
 plain index scan.

 So the only concern I have here is your seq scan one.  Sadly I can't
 replicate with a smaller test sample even on my windows 64-bit 9.6.2
 running PostGIS 2.4 dev (which should be more or less the same as 2.3.2)
 and same makeup as yours.

 Here is my vein attempt just using full NJ state data I had lying around
 and using the same indexes you have except the iso had to replace with iso
 2 since I didn't have iso 1.


 {{{
 EXPLAIN  ANALYZE SELECT  ap.tags->'ISO3166-2' iso,s.admin_level admlev,
 s.way, s.osm_id
 FROM planet_osm_polygon s
 JOIN planet_osm_polygon ap on ST_Within(s.way,ap.way)
 WHERE  ap.tags?'ISO3166-2' AND ap.tags->'ISO3166-2' in ('US-NJ')  AND
 s.admin_level ~ '^\d+$';


 QUERY PLAN
 -----------------------------------------------------------------------------------------------
  Nested Loop  (cost=4.30..28.74 rows=1 width=7236) (actual
 time=2.629..389.108 rows=488 loops=1)
    ->  Index Scan using polygon_iso3166_2_idx on planet_osm_polygon ap
 (cost=0.13..8.14 rows=1 width=7231) (actual time=0.015..0.016 rows=1
 loops=1)
          Index Cond: ((tags -> 'ISO3166-2'::text) = 'US-NJ'::text)
    ->  Bitmap Heap Scan on planet_osm_polygon s  (cost=4.18..20.58 rows=1
 width=7204) (actual time=2.283..386.256 rows=488 loops=1)
          Recheck Cond: (ap.way ~ way)
          Filter: (((admin_level)::text ~ '^\d+$'::text) AND
 _st_contains(ap.way, way))
          Rows Removed by Filter: 3124
          Heap Blocks: exact=1348
          ->  Bitmap Index Scan on planet_osm_polygon_index
 (cost=0.00..4.18 rows=4 width=0) (actual time=0.594..0.594 rows=3612
 loops=1)
                Index Cond: (ap.way ~ way)
  Planning time: 4.018 ms
  Execution time: 392.913 ms
 (12 rows)
 }}}


 {{{
 EXPLAIN  ANALYZE SELECT  ap.tags->'ISO3166-2' iso,s.admin_level admlev,
 s.way, s.osm_id
 FROM planet_osm_polygon s
 JOIN planet_osm_polygon ap on ap.way ~ s.way AND ST_Within(s.way,ap.way)
 WHERE  ap.tags?'ISO3166-2' AND ap.tags->'ISO3166-2' in ('US-NJ')  AND
 s.admin_level ~ '^\d+$';


 QUERY PLAN
 ------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop  (cost=0.27..16.58 rows=1 width=7236) (actual
 time=1.707..398.057 rows=488 loops=1)
    ->  Index Scan using polygon_iso3166_2_idx on planet_osm_polygon ap
 (cost=0.13..8.14 rows=1 width=7231) (actual time=0.016..0.017 rows=1
 loops=1)
          Index Cond: ((tags -> 'ISO3166-2'::text) = 'US-NJ'::text)
    ->  Index Scan using planet_osm_polygon_index on planet_osm_polygon s
 (cost=0.15..8.42 rows=1 width=7204) (actual time=1.480..395.016 rows=488
 loops=1)
          Index Cond: ((ap.way ~ way) AND (ap.way ~ way))
          Filter: (((admin_level)::text ~ '^\d+$'::text) AND
 _st_contains(ap.way, way))
          Rows Removed by Filter: 3124
  Planning time: 0.156 ms
  Execution time: 398.725 ms
 (9 rows)

 }}}


 {{{

 SET enable_bitmapscan = false;
 EXPLAIN  ANALYZE SELECT  ap.tags->'ISO3166-2' iso,s.admin_level admlev,
 s.way, s.osm_id
 FROM planet_osm_polygon s
 JOIN planet_osm_polygon ap on  ST_Within(s.way,ap.way)
 WHERE  ap.tags?'ISO3166-2' AND ap.tags->'ISO3166-2' in ('US-NJ')  AND
 s.admin_level ~ '^\d+$';

 QUERY PLAN
 -------------------------------------------------------------------------------------------------------------------------------------------------------------
  Nested Loop  (cost=0.27..29.38 rows=1 width=7236) (actual
 time=1.607..402.173 rows=488 loops=1)
    ->  Index Scan using polygon_iso3166_2_idx on planet_osm_polygon ap
 (cost=0.13..8.14 rows=1 width=7231) (actual time=0.007..0.008 rows=1
 loops=1)
          Index Cond: ((tags -> 'ISO3166-2'::text) = 'US-NJ'::text)
    ->  Index Scan using planet_osm_polygon_index on planet_osm_polygon s
 (cost=0.15..21.23 rows=1 width=7204) (actual time=1.545..397.700 rows=488
 loops=1)
          Index Cond: (ap.way ~ way)
          Filter: (((admin_level)::text ~ '^\d+$'::text) AND
 _st_contains(ap.way, way))
          Rows Removed by Filter: 3124
  Planning time: 0.159 ms
  Execution time: 402.805 ms
 (9 rows)
 }}}


 See in above the execution time the bitmap is fastest and even when you
 add in planning it's still faster.
 You can fiddle with maybe enable_seqscan=false to see what it does if it
 makes it go the right way.

 It would be great if you can maybe try the above example too on your
 machine - to rule out machine/PostgreSQL version/ postgrsql settings
 specific issues.

 The data I used was - http://postgis.us/downloads/nj.osm.pbf

 If your bounding boxes are big enough (which is a especially big problem
 when using long lat projection and comparing countries), it could dismiss
 using an index entirely because it thinks its useless, never even bothers
 costing.  The extra ~ would just add some extra
 incentive to make it consider the plan.  pramsey can describe the innards
 better but I do think the histogram is used in some shape or form for the
 planner to decide if a plan is even worth considering.

--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3739#comment:19>
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