Postgres - статьи

Сегментирование данных


Сегментирование данных можно организовать с помощью наследования (TABLE INHERITANCE) и CE (CONSTRAINT EXCLUSION). Идея состоит в том, чтобы иметь родительскую таблицу (класс), которая определяет основной набор атрибутов и таблицы, которые наследуют структуру родительской таблицы, но имеющие определенные ограничения на параметр, по которому проводится сегментирование. Механизм наследования в PostgreSQL обеспечивает выполнение запроса по всем таблицам автоматически, при этом наличие CE позволяет просматривать только те таблицы, которые удовлетворяют условию на параметр.

Типичная ситуация, когда сегментирование идет по времени, например, для хранение журналов веб-серверов.

В нашем примере мы создаем таблицу apod_class и две таблицы, которые наследуют ее. Эти таблицы наследуют структуру родительской таблицы, но при этом могут иметь свои специфические атрибуты. Таблица apod_new предназначена для новых сообщений, а apod_archive для неизменяющихся архивных документов. Заметим, что для новых сообщений мы создали GiST индекс, который очень хорошо обновляется, а для архивной таблицы создали GIN индекс, который очень хорошо шкалируется, но обновление, как и для всех обратных индексов, происходит очень медленно.

CREATE TABLE apod_class ( id integer, title text, body text, sdate date, keywords text, fts tsvector ); CREATE TABLE apod_new ( CHECK ( sdate >2001-08-08 ) ) INHERITS (apod_class); CREATE INDEX gist_idx ON apod_new USING gist(fts);

CREATE TABLE apod_archive ( CHECK ( sdate ≤2001-08-08 ) ) INHERITS (apod_class); CREATE INDEX gist_idx ON apod_new USING gin(fts);

PostgreSQL позволяет искать как по всей коллекции, указав таблицу apod_class, так и по отдельным частям. В зависимости от задачи, сегментировать данные можно и по большему количеству таблиц, например, распределять документы по годам, месяцам. Оптимизатор PostgreSQL автоматически выбирает только те таблицы, которые удовлетворяют условию CHECK, что очень благоприятно сказывается на производительности запросов. Например, для запроса

apod=# select title,rank_cd(fts, q) from apod_class, to_tsquery('stars') q where fts @@ q order by rank_cd desc limit 5;

будут просматриваться две таблицы, а для запроса

apod=# select title,rank_cd(fts, q) from apod_class, to_tsquery('stars') q where fts @@ q and sdate > 2001-08-08 order by rank_cd desc limit 5;

будет использоваться только таблица apod_new. Отметим, что для этого необходимо включить CONSTRAINT EXCLUSION

SET constraint_exclusion TO on;



Содержание раздела