为什么要从联接中的查询条件中排除所有分区表,为什么要扫描它们?

时间:2019-06-09 19:41:50

标签: postgresql postgis

我有两个表:一个是基于有效时间的分区表,第二个是具有有效时间和到期时间的状态表。我也有一个视图,该视图将状态表连接到分区表,并尝试将分区表的搜索范围缩小到仅那些尚未过期的分区。

我尝试使用单独的validtime列,因此where子句中的那个不与分区中的那个绑定,但是查询计划程序仅在那些情况下才对几何显示索引扫描,并且仍然对分区上的索引进行扫描不能根据有效期限包含有效结果。

分区表如下:

CREATE TABLE public.poly__20190609__171000
(
-- Inherited from table poly:  ogc_featureid bigint NOT NULL DEFAULT nextval('poly_ogc_featureid_seq'::regclass),
-- Inherited from table poly:  validtime timestamp without time zone,
-- Inherited from table poly:  geometry_4326 geometry(Polygon,4326) NOT NULL,
  CONSTRAINT poly_20190609_171000_pkey PRIMARY KEY (ogc_featureid),
  CONSTRAINT poly_20190609_171000_check CHECK (validtime >= '2019-06-09 17:10:00'::timestamp without time zone AND validtime <= '2019-06-09 17:14:59'::timestamp without time zone)
);
CREATE INDEX poly__20190609__171000_4326_gist
  ON public.poly__20190609__171000
  USING gist
  (geometry_4326);
CREATE INDEX poly__20190609__171000_validtime_idx
  ON public.poly__20190609__171000
  USING btree
  (validtime);

状态表如下:

CREATE TABLE public.poly_current_state
(
  validtime timestamp without time zone NOT NULL,
  current_expiration timestamp without time zone NOT NULL,
  CONSTRAINT poly_current_state_pkey PRIMARY KEY (validtime)
);

视图如下:

CREATE VIEW public.example_view AS
 SELECT p.ogc_featureid,
    pcs.validtime,
    pcs.current_expiration AS expiration,
    p.geometry_4326
   FROM poly_current_state pcs
   INNER JOIN poly p ON p.validtime = pcs.validtime;

查询示例如下:

SELECT "expiration","validtime" 
  FROM "public"."example_view" 
 WHERE (
   "validtime" < '2019-06-09T18:30:00Z' 
   AND "expiration" > '2019-06-09T18:00:00Z' 
   AND ST_DWithin("geometry_4326",ST_GeomFromText('MULTILINESTRING ((-130 35, -65 35))', 4326),3.3333333333333335) 
   ) LIMIT 1;

查询的解释(为了保护无辜的二进制几何被截断)如下所示(请注意,在到期前很长一段时间(有效时间之后最多15分钟)内包含前两行有效):

Limit  (cost=0.05..11.25 rows=1 width=16)
  ->  Nested Loop  (cost=0.05..274278.59 rows=24506 width=16)
        ->  Append  (cost=0.00..268347.87 rows=92105 width=11)
              ->  Seq Scan on poly p  (cost=0.00..0.00 rows=1 width=20)
                    Filter: ((validtime < '2019-06-09 18:30:00'::timestamp without time zone) AND (geometry_4326 && '010300002...'::geometry) AND ('01050000...'::geometry && st_expand(geometry_4326, 3.33333333333333::double precision)) AND
              ->  Bitmap Heap Scan on poly__20190609__151500 p_1  (cost=845.99..6160.40 rows=2037 width=11)
                    Recheck Cond: (geometry_4326 && '010300002...'::geometry)
                    Filter: ((validtime < '2019-06-09 18:30:00'::timestamp without time zone) AND ('01050000...'::geometry && st_expand(geometry_4326, 3.33333333333333::double precision)) AND _st_dwithin(geometry_4326, '01050000...'::geomet
                    ->  Bitmap Index Scan on poly__20190609__151500_4326_gist  (cost=0.00..845.89 rows=30553 width=0)
                          Index Cond: (geometry_4326 && '010300002...'::geometry)
              ->  Bitmap Heap Scan on poly__20190609__152000 p_2  (cost=870.03..6217.87 rows=2039 width=11)
                    Recheck Cond: (geometry_4326 && '010300002...'::geometry)
                    Filter: ((validtime < '2019-06-09 18:30:00'::timestamp without time zone) AND ('01050000...'::geometry && st_expand(geometry_4326, 3.33333333333333::double precision)) AND _st_dwithin(geometry_4326, '01050000...'::geomet
                    ->  Bitmap Index Scan on poly__20190609__152000_4326_gist  (cost=0.00..869.92 rows=30579 width=0)
                          Index Cond: (geometry_4326 && '010300002...'::geometry)
              ...
              ->  Bitmap Heap Scan on poly__20190609__182500 p_39  (cost=1159.25..7559.40 rows=2803 width=11)
                    Recheck Cond: (geometry_4326 && '010300002...'::geometry)
                    Filter: ((validtime < '2019-06-09 18:30:00'::timestamp without time zone) AND ('01050000...'::geometry && st_expand(geometry_4326, 3.33333333333333::double precision)) AND _st_dwithin(geometry_4326, '01050000...'::geomet
                    ->  Bitmap Index Scan on poly__20190609__182500_4326_gist  (cost=0.00..1159.11 rows=42039 width=0)
                          Index Cond: (geometry_4326 && '010300002...'::geometry)
        ->  Index Only Scan using poly_current_state_a_idx on poly_current_state pcs  (cost=0.05..0.06 rows=1 width=19)
              Index Cond: ((validtime = p.validtime) AND (current_expiration > '2019-06-09 18:00:00'::timestamp without time zone))

我正在使用Postgres 9.3(我知道,但是升级不是即时选择)。

0 个答案:

没有答案