Сканирование растрового изображения в новых секционированных таблицах - PullRequest
1 голос
/ 01 марта 2020

Я использую разделение таблиц для хранения сообщений, разбитых по месяцам. В этом месяце наш веб-сайт вышел из строя, потому что запросы на новый месяц работали очень плохо. До сих пор не знаю, почему.

Объясните запрос за предыдущий месяц (~ 200M строк)

https://explain.depesz.com/s/yGDH

Объясните для того же запроса в текущем месяце (~ 400 тыс. строк)

https://explain.depesz.com/s/g7fV

Как видно из пояснений, используется сканирование индекса (conv_id, с включенным фильтром). «создал»), а другой сначала выполняет сканирование кучи растрового изображения после сканирования индекса растрового изображения.

Структура таблицы:

CREATE TABLE conv_messages
(
    conv_message_id bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1 ),
    conv_id bigint NOT NULL,
    message text COLLATE pg_catalog."default" NOT NULL,
    message_type smallint NOT NULL DEFAULT 1,
    created timestamp without time zone NOT NULL DEFAULT now(),
    unread boolean NOT NULL DEFAULT true,
    from_user_id integer NOT NULL,
    CONSTRAINT convmessages_pkey PRIMARY KEY (conv_message_id, created)
) PARTITION BY RANGE (created) ;


CREATE INDEX conv_messages_unreads
    ON conv_messages USING btree
    (unread ASC NULLS LAST)
    TABLESPACE pg_default
    WHERE unread IS TRUE;

CREATE INDEX ix_convm_user_id
    ON conv_messages USING btree
    (from_user_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE INDEX ix_convmessages_convid
    ON conv_messages USING btree
    (conv_id ASC NULLS LAST)
    TABLESPACE pg_default;

CREATE INDEX ix_convmessages_created
    ON conv_messages USING btree
    (created DESC NULLS FIRST)
    TABLESPACE pg_default;

и (простой) запрос:

select * from conv_messages m
    where
     m.created >= '2020-03-01 00:00:00' and
     m.created < '2020-04-01 00:00:00' and
     m.conv_id = 259395024
    order by m.created desc
    limit 20  offset 0;

Я не понимаю, почему разделенная таблица с 200m + строками работает в 40 раз быстрее, чем таблица с только 400k строками, учитывая, что таблицы одинаковы. Я попытался переиндексации create_ix и conv_id_ix, но это не имело никакого значения.

Кто-нибудь знает, что здесь может происходить? Я использую postgresql 12

1 Ответ

1 голос
/ 02 марта 2020

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...