Постоянная агрегация

1. Введение

На практике агрегационные запросы встречаются очень часто. Поскольку такие запросы, как правило, основаны на базовых наборах данных большого объёма и включают операции суммирования, группировки и агрегации, они обычно считаются относительно ресурсоёмкими и чаще всего используются в аналитических сценариях. Кроме того, частота выполнения агрегационных запросов в реальных условиях постоянно возрастает, а требования к времени отклика становятся всё выше.

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

2. Использование

2.1 Создание расширения

Для постоянной агрегации требуется расширение matrixts. Сначала необходимо создать это расширение:

CREATE EXTENSION matrixts;

2.2 Создание таблицы данных

Таблица данных — это исходная таблица с данными:

CREATE TABLE metrics(
    time timestamp,
    tag_id int,
    sensor float4
)
Distributed by(tag_id);

2.3 Создание представления постоянной агрегации

Постоянная агрегация использует материализованные представления для хранения результатов агрегации. При создании представления необходимо указать ключевое слово WITH (CONTINUOUS) и инструкцию агрегации:

CREATE VIEW cv1 WITH (CONTINUOUS) AS
    SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics GROUP BY tag_id;

2.4 Вставка данных в исходную таблицу

INSERT INTO metrics VALUES(NOW(), 1, 1.1);
INSERT INTO metrics VALUES(NOW(), 1, 1.2);
INSERT INTO metrics VALUES(NOW(), 2, 2.1);
INSERT INTO metrics VALUES(NOW(), 2, 2.2);

2.5 Запрос к представлению постоянной агрегации

При использовании постоянной агрегации достаточно вставлять последовательные во времени данные в исходную таблицу — материализованное представление будет автоматически вычислять результат:

SELECT * FROM cv1 ORDER BY tag_id;
 tag_id | count |    sum
-------+-------+---------------
      1 |     2 | 2.3000002
      2 |     2 |       4.3
(2 rows)

Результаты материализованного представления совпадают с результатами агрегации по исходной таблице:

SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics
    GROUP BY tag_id
    ORDER BY tag_id;
 tag_id | count |    sum
-------+-------+---------------
      1 |     2 | 2.3000002
      2 |     2 |       4.3
(2 rows)

Если в исходной таблице уже есть данные на момент создания постоянной агрегации, они будут синхронизированы по умолчанию. Если синхронизация не требуется, при создании представления нужно вручную установить параметр POPULATE в значение false (по умолчанию используется true):

CREATE VIEW cv1 WITH (CONTINUOUS, POPULATE=false) AS
    SELECT tag_id, COUNT(*), SUM(sensor)
    FROM metrics GROUP BY tag_id;

3. Методы обслуживания

MatrixDB предоставляет пользовательские функции (UDF) для обслуживания постоянной агрегации:

  • matrixts_internal.analyze_continuous_view(rel REGCLASS)

    Выполнение ANALYZE над материализованным представлением позволяет обновить статистику, что способствует оптимизации запросов: SELECT matrixts_internal.analyze_continuous_view('cv1');

  • matrixts_internal.vacuum_continuous_view(rel REGCLASS, full BOOL)

    VACUUM над материализованным представлением очищает "мёртвые" кортежи и обеспечивает повторное использование пространства; если второй параметр равен true, файл таблицы будет перестроен, что приведёт к уменьшению занимаемого места: SELECT matrixts_internal.vacuum_continuous_view('cv1', true);

  • matrixts_internal.rebuild_continuous_view(rel REGCLASS)

    Перестройка материализованного представления подходит для случаев, когда в исходной таблице происходят обновления или удаления, и требуется полная синхронизация данных: SELECT matrixts_internal.rebuild_continuous_view('cv1');

4. Часто задаваемые вопросы

  1. Происходит ли синхронизация данных материализованного представления с исходной таблицей в реальном времени?

    • Да, после вставки данных в исходную таблицу они сразу доступны для запроса из материализованного представления.
  2. Обеспечивает ли постоянная агрегация ACID-гарантии?

    • Да, данные в материализованном представлении используют тот же идентификатор транзакции, что и данные исходной таблицы.
  3. Как обрабатываются операции обновления и удаления?

    • Операции обновления, удаления и DROP исходной таблицы не отражаются в представлении постоянной агрегации, однако поддерживаются upsert-обновления и агрегация последнего непустого значения (last_not_null).
  4. Поддерживаются ли оконные функции в постоянной агрегации?

    • Оконные функции пока не поддерживаются.
  5. Поддерживает ли постоянная агрегация секционированные таблицы?

    • Поддерживает.
  6. Поддерживает ли постоянная агрегация агрегацию по нескольким таблицам?

    • Нет, не поддерживает.
  7. Можно ли определить несколько постоянных агрегаций для одной таблицы?

    • Да, можно.