Postgres PostGIS左连接查询性能

时间:2016-07-26 14:48:08

标签: sql postgresql postgis postgresql-performance

db结构或多或少是这样的,不能修改。我只能添加一些索引,但不能设置例如外键:

#define basename    __xpg_basename

我有这样的查询:

    CREATE TABLE adresspoint
(
  id character varying(3999) NOT NULL,
  "position" geometry(PointZ,25832)
  CONSTRAINT pk_adresspoint PRIMARY KEY (id)
)

CREATE INDEX adresspoint_idx_position
  ON adresspoint
  USING gist
  ("position");

CREATE TABLE house
(
  id character varying(3999) NOT NULL,
  adresspointid character varying(3999),
  CONSTRAINT pk_house PRIMARY KEY (id)
)

CREATE INDEX house_idx_adresspointid
  ON house
  USING btree
  (adresspointid COLLATE pg_catalog."default");

并且它运行得非常快(100毫秒),但当我将其更改为:

SELECT DISTINCT house.id 
FROM house 
   LEFT JOIN adresspoint ON adresspoint.id = house.adresspointid 
             AND st_contains(st_makeenvelope('562827','6326412','563365','6326590',25832),adresspoint.position)
OFFSET 0 LIMIT 10

它运行得非常慢(比较慢100倍)。

我想知道它背后的原因是什么,有什么方法可以优化它?我有位置,ids等索引。

以下是执行计划:

更快:

SELECT DISTINCT house.id 
FROM house 
  LEFT JOIN adresspoint ON adresspoint.id = house.adresspointid 
        AND st_contains(st_makeenvelope('562827','6326412','563365','6326590',25832),adresspoint.position)
WHERE adresspoint.id is not null -- ***change is here***
OFFSET 0 LIMIT 10

慢:

Limit  (cost=657.35..9907.84 rows=10 width=86) (actual time=6.864..7.036 rows=10 loops=1)
         ->  Nested Loop Anti Join  (cost=657.35..632794743.21 rows=6682119 width=86) (actual time=6.852..6.978 rows=10 loops=1)
               Join Filter: ((adresspoint.id)::text = (house.adresspointid)::text)
               ->  Index Scan using pk_house on pk_house house (cost=0.56..17531908.09 rows=6841197 width=123) (actual time=0.077..0.159 rows=10 loops=1)
               ->  Materialize  (cost=656.80..68209.88 rows=5995 width=37) (actual time=0.678..0.678 rows=0 loops=10)
                     ->  Bitmap Heap Scan on adresspoint  (cost=656.80..68179.90 rows=5995 width=37) (actual time=6.757..6.757 rows=0 loops=1)
                           Recheck Cond: ('0103000020E86'::geometry ~ "position")
                           Filter: _st_contains('010300002'::geometry, "position")
                           ->  Bitmap Index Scan on adresspoint_idx_position  (cost=0.00..655.30 rows=17984 width=0) (actual time=6.737..6.737 rows=0 loops=1)
                                 Index Cond: ('0103000020E86'::geometry ~ "position")
 Planning time: 22.333 ms
 Execution time: 7.634 ms

0 个答案:

没有答案