为什么POSTGIS不使用geom索引< - >操作者

时间:2015-10-29 21:10:45

标签: sql postgresql postgis

使用<->订单应该更快

     SELECT *
     FROM (
        SELECT 
                id::integer as id_out, 
                ST_Distance(f.geom, g.geom  )*100000 as distance
        FROM 
                rto g, (SELECT geom FROM rto WHERE id = 802343) f
        ORDER BY 
                g.geom <-> f.geom
        LIMIT 101
   ) as T
    ORDER BY distance
    LIMIT 10

使用排序键但不使用geom索引

"Limit  (cost=222681.59..222681.61 rows=10 width=12)"
"  ->  Sort  (cost=222681.59..222681.84 rows=101 width=12)"
"        Sort Key: t.distance"
"        ->  Subquery Scan on t  (cost=222678.14..222679.40 rows=101 width=12)"
"              ->  Limit  (cost=222678.14..222678.39 rows=101 width=200)"
"                    ->  Sort  (cost=222678.14..224279.59 rows=640578 width=200)"
"                          Sort Key: ((g.geom <-> rto.geom))"
"                          ->  Nested Loop  (cost=0.00..198149.73 rows=640578 width=200)"
"                                ->  Index Scan using id_idx on rto  (cost=0.00..8.34 rows=1 width=97)"
"                                      Index Cond: (id = 802343::numeric)"
"                                ->  Seq Scan on rto g  (cost=0.00..26786.78 rows=640578 width=103)"

删除<->运算符的速度更快

     SELECT *
     FROM (
        SELECT 
                id::integer as id_out, 
                ST_Distance(f.geom, g.geom  )*100000 as distance
        FROM 
                rto g, (SELECT geom FROM rto WHERE id = 802343) f
   ) as T
    ORDER BY distance
    LIMIT 10


"Limit  (cost=210390.95..210390.97 rows=10 width=200)"
"  ->  Sort  (cost=210390.95..211992.39 rows=640578 width=200)"
"        Sort Key: ((st_distance(rto.geom, g.geom) * 100000::double precision))"
"        ->  Nested Loop  (cost=0.00..196548.29 rows=640578 width=200)"
"              ->  Index Scan using id_idx on rto  (cost=0.00..8.34 rows=1 width=97)"
"                    Index Cond: (id = 802343::numeric)"
"              ->  Seq Scan on rto g  (cost=0.00..26786.78 rows=640578 width=103)"
  • Postgresql 9.2
  • Postgis 2.1
  • Windows 7

1 个答案:

答案 0 :(得分:0)

我不确定为什么它没有使用索引,我打赌它会认为子查询可能会返回多行。

要使其使用更好的计划,请重写它以使用LATERAL联接

  SELECT *
     FROM (
        SELECT 
                id::integer as id_out, 
                ST_Distance(f.the_geom, g.the_geom  )*100000 as distance
        FROM 
        rto f           
                CROSS JOIN LATERAL (SELECT the_geom FROM rto g ORDER BY 
                g.the_geom <-> f.the_geom
        LIMIT 101) g
        WHERE f.id = 5999 

   ) as T
    ORDER BY distance
    LIMIT 10