Почему все многораздельные таблицы сканируются, если они должны быть исключены по критериям запроса из объединения? - PullRequest
0 голосов
/ 09 июня 2019

У меня есть две таблицы: одна - это секционированная таблица, основанная на действительном времени, а вторая - таблица состояний, которая имеет действительное время и время истечения.У меня также есть представление, которое присоединяет таблицу состояний для присоединения к многораздельной таблице и пытается сузить поиск многораздельной таблицы только для тех разделов, которые не просрочены.

Я попытался использовать отдельные столбцы 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 (я знаю, но обновление ненемедленная опция).

...