Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么PostgreSQL在此查询中进行顺序扫描而不是索引扫描?_Postgresql_Openstreetmap_Postgis - Fatal编程技术网

为什么PostgreSQL在此查询中进行顺序扫描而不是索引扫描?

为什么PostgreSQL在此查询中进行顺序扫描而不是索引扫描?,postgresql,openstreetmap,postgis,Postgresql,Openstreetmap,Postgis,我正在使用OpenStreetMap osm2pgsql数据库。其中一个表(planet_osm_line)有两个索引字段:osm_id(int,主键)和way(postgis几何体) 我想找出哪些街道与特定街道相交,我通过它的osm_id知道。所以我: SELECT name, * FROM planet_osm_line WHERE highway IS NOT NULL AND osm_id != 126021312 AND ST_Intersects(way, (SELECT way F

我正在使用OpenStreetMap osm2pgsql数据库。其中一个表(planet_osm_line)有两个索引字段:osm_id(int,主键)和way(postgis几何体)

我想找出哪些街道与特定街道相交,我通过它的osm_id知道。所以我:

SELECT name, * FROM planet_osm_line
WHERE highway IS NOT NULL
AND osm_id != 126021312
AND ST_Intersects(way, (SELECT way FROM planet_osm_line WHERE osm_id = 126021312 LIMIT 1))
运行大约需要10秒

相反,如果我取出该子查询并单独运行,它看起来如下所示:

SELECT name, * FROM planet_osm_line
WHERE highway IS NOT NULL
AND osm_id != 126021312
AND ST_Intersects(way, '010200002031BF0D000D000000E17...')
运行大约需要0.47秒

在第一个查询和第二个查询上运行EXPLAIN会给我一个关于差异的提示

第一:

Seq Scan on planet_osm_line  (cost=2.09..614596.67 rows=628706 width=1079)
  Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND st_intersects(way, $0))
  InitPlan 1 (returns $0)
    ->  Limit  (cost=0.43..2.09 rows=1 width=249)
          ->  Index Scan using planet_osm_line_pkey on planet_osm_line planet_osm_line_1  (cost=0.43..3.76 rows=2 width=249)
                Index Cond: (osm_id = 126021312)
行星osm线上的序列扫描(成本=2.09..614596.67行=628706宽度=1079) 过滤器:((高速公路不为空)和(osm_id 126021312)与st_相交(道路,$0)) InitPlan 1(返回$0) ->限制(成本=0.43..2.09行=1宽=249) ->使用planet_osm_line planet_osm_line 1上的planet_osm_line_pkey进行索引扫描(成本=0.43..3.76行=2宽=249) 索引条件:(osm_id=126021312) 第二:

Index Scan using planet_osm_line_index on planet_osm_line  (cost=0.41..4.25 rows=1 width=1079)
  Index Cond: (way && '010200002031BF0D000D000000E17...'::geometry)
  Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND _st_intersects(way, '010200002031BF0D000D000000E17...'::geometry))
使用planet_osm_line_索引对planet_osm_line进行索引扫描(成本=0.41..4.25行=1宽度=1079)
索引条件:(方式和“010200002031BF0D000D000000E17…”:几何)
过滤器:((高速公路不为空)和(osm_id 126021312)和_st_相交(道路,'010200002031BF0D000D000000E17…'::几何图形))

为什么PostgreSQL在第一个页面上进行seq扫描,在第二个页面上进行索引扫描?有没有办法在不发出两个查询的情况下解决这个问题?

重写您的查询,这样您就不用在ST_Intersects中有子查询,而是在FROM中有一个交叉连接,然后它将受到WHERE中的相交的限制(这也隐式地执行&,即边界框检查,它将命中空间索引).


重写您的查询,以便在FROM中有一个交叉连接,而不是在ST_Intersects中有一个子查询,它将受到WHERE中的交叉连接的限制(这也隐式地执行&,即边界框检查,它将命中空间索引)


重写您的查询,以便在FROM中有一个交叉连接,而不是在ST_Intersects中有一个子查询,它将受到WHERE中的交叉连接的限制(这也隐式地执行&,即边界框检查,它将命中空间索引)


重写您的查询,以便在FROM中有一个交叉连接,而不是在ST_Intersects中有一个子查询,它将受到WHERE中的交叉连接的限制(这也隐式地执行&,即边界框检查,它将命中空间索引)


这种方式似乎很好(部分回答了我的问题):

对它的解释表明,PostgreSQL似乎在做我首先想要做的事情:

Nested Loop  (cost=6.80..577.98 rows=7451 width=1108)
  ->  Index Scan using planet_osm_line_pkey on planet_osm_line l2  (cost=0.43..3.76 rows=2 width=249)
      Index Cond: (osm_id = 126021312)
  ->  Bitmap Heap Scan on planet_osm_line l1  (cost=6.37..286.48 rows=63 width=1108)
        Recheck Cond: (way && l2.way)
        Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND _st_intersects(way, l2.way))
        ->  Bitmap Index Scan on planet_osm_line_index  (cost=0.00..6.36 rows=206 width=0)
            Index Cond: (way && l2.way)
嵌套循环(成本=6.80..577.98行=7451宽度=1108)
->使用planet_osm_line_pkey在planet_osm_line l2上进行索引扫描(成本=0.43..3.76行=2宽度=249)
索引条件:(osm_id=126021312)
->planet_osm_行l1上的位图堆扫描(成本=6.37..286.48行=63宽度=1108)
重新检查条件:(方式和二级方式)
过滤器:((高速公路不为空)和(osm_id 126021312)和_st_相交(路,l2.way))
->planet_osm_line_索引上的位图索引扫描(成本=0.00..6.36行=206宽度=0)
索引条件:(方式和二级方式)

不过,我仍然很好奇为什么第一个查询的行为与此不同。

这种方式似乎很好(部分回答了我的问题):

对它的解释表明,PostgreSQL似乎在做我首先想要做的事情:

Nested Loop  (cost=6.80..577.98 rows=7451 width=1108)
  ->  Index Scan using planet_osm_line_pkey on planet_osm_line l2  (cost=0.43..3.76 rows=2 width=249)
      Index Cond: (osm_id = 126021312)
  ->  Bitmap Heap Scan on planet_osm_line l1  (cost=6.37..286.48 rows=63 width=1108)
        Recheck Cond: (way && l2.way)
        Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND _st_intersects(way, l2.way))
        ->  Bitmap Index Scan on planet_osm_line_index  (cost=0.00..6.36 rows=206 width=0)
            Index Cond: (way && l2.way)
嵌套循环(成本=6.80..577.98行=7451宽度=1108)
->使用planet_osm_line_pkey在planet_osm_line l2上进行索引扫描(成本=0.43..3.76行=2宽度=249)
索引条件:(osm_id=126021312)
->planet_osm_行l1上的位图堆扫描(成本=6.37..286.48行=63宽度=1108)
重新检查条件:(方式和二级方式)
过滤器:((高速公路不为空)和(osm_id 126021312)和_st_相交(路,l2.way))
->planet_osm_line_索引上的位图索引扫描(成本=0.00..6.36行=206宽度=0)
索引条件:(方式和二级方式)

不过,我仍然很好奇为什么第一个查询的行为与此不同。

这种方式似乎很好(部分回答了我的问题):

对它的解释表明,PostgreSQL似乎在做我首先想要做的事情:

Nested Loop  (cost=6.80..577.98 rows=7451 width=1108)
  ->  Index Scan using planet_osm_line_pkey on planet_osm_line l2  (cost=0.43..3.76 rows=2 width=249)
      Index Cond: (osm_id = 126021312)
  ->  Bitmap Heap Scan on planet_osm_line l1  (cost=6.37..286.48 rows=63 width=1108)
        Recheck Cond: (way && l2.way)
        Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND _st_intersects(way, l2.way))
        ->  Bitmap Index Scan on planet_osm_line_index  (cost=0.00..6.36 rows=206 width=0)
            Index Cond: (way && l2.way)
嵌套循环(成本=6.80..577.98行=7451宽度=1108)
->使用planet_osm_line_pkey在planet_osm_line l2上进行索引扫描(成本=0.43..3.76行=2宽度=249)
索引条件:(osm_id=126021312)
->planet_osm_行l1上的位图堆扫描(成本=6.37..286.48行=63宽度=1108)
重新检查条件:(方式和二级方式)
过滤器:((高速公路不为空)和(osm_id 126021312)和_st_相交(路,l2.way))
->planet_osm_line_索引上的位图索引扫描(成本=0.00..6.36行=206宽度=0)
索引条件:(方式和二级方式)

不过,我仍然很好奇为什么第一个查询的行为与此不同。

这种方式似乎很好(部分回答了我的问题):

对它的解释表明,PostgreSQL似乎在做我首先想要做的事情:

Nested Loop  (cost=6.80..577.98 rows=7451 width=1108)
  ->  Index Scan using planet_osm_line_pkey on planet_osm_line l2  (cost=0.43..3.76 rows=2 width=249)
      Index Cond: (osm_id = 126021312)
  ->  Bitmap Heap Scan on planet_osm_line l1  (cost=6.37..286.48 rows=63 width=1108)
        Recheck Cond: (way && l2.way)
        Filter: ((highway IS NOT NULL) AND (osm_id <> 126021312) AND _st_intersects(way, l2.way))
        ->  Bitmap Index Scan on planet_osm_line_index  (cost=0.00..6.36 rows=206 width=0)
            Index Cond: (way && l2.way)
嵌套循环(成本=6.80..577.98行=7451宽度=1108)
->使用planet_osm_line_pkey在planet_osm_line l2上进行索引扫描(成本=0.43..3.76行=2宽度=249)
索引条件:(osm_id=126021312)
->planet_osm_行l1上的位图堆扫描(成本=6.37..286.48行=63宽度=1108)
重新检查条件:(方式和二级方式)
过滤器:((高速公路不为空)和(osm_id 126021312)和_st_相交(路,l2.way))
->planet_osm_line_索引上的位图索引扫描(成本=0.00..6.36行=206宽度=0)
索引条件:(方式和二级方式)
不过,我仍然很好奇为什么第一个查询的行为与此不同。

(从planet_osm_行中选择路径,其中osm_id=126021312 LIMI)