Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com>
18 KiB
toc_priority | toc_title |
---|---|
37 | Представление |
CREATE VIEW
Создаёт представление. Представления бывают двух видов - обычные и материализованные (MATERIALIZED).
Обычные представления
CREATE [OR REPLACE] VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] AS SELECT ...
Обычные представления не хранят никаких данных, они выполняют чтение данных из другой таблицы при каждом доступе. Другими словами, обычное представление — это не что иное, как сохраненный запрос. При чтении данных из представления этот сохраненный запрос используется как подзапрос в секции FROM.
Для примера, пусть вы создали представление:
CREATE VIEW view AS SELECT ...
и написали запрос:
SELECT a, b, c FROM view
Этот запрос полностью эквивалентен использованию подзапроса:
SELECT a, b, c FROM (SELECT ...)
Материализованные представления
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
Материализованные (MATERIALIZED) представления хранят данные, преобразованные соответствующим запросом SELECT.
При создании материализованного представления без использования TO [db].[table]
, нужно обязательно указать ENGINE
- движок таблицы для хранения данных.
При создании материализованного представления с испольованием TO [db].[table]
, нельзя указывать POPULATE
.
Материализованное представление устроено следующим образом: при вставке данных в таблицу, указанную в SELECT-е, кусок вставляемых данных преобразуется этим запросом SELECT, и полученный результат вставляется в представление.
!!! important "Важно"
Материализованные представления в ClickHouse больше похожи на after insert
триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление.
Если указано POPULATE
, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос CREATE TABLE ... AS SELECT ...
. Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать POPULATE, так как вставляемые в таблицу данные во время создания представления, не попадут в него.
Запрос SELECT
может содержать DISTINCT
, GROUP BY
, ORDER BY
, LIMIT
… Следует иметь ввиду, что соответствующие преобразования будут выполняться независимо, на каждый блок вставляемых данных. Например, при наличии GROUP BY
, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы. Исключение - использование ENGINE, производящего агрегацию данных самостоятельно, например, SummingMergeTree
.
Недоработано выполнение запросов ALTER
над материализованными представлениями, поэтому они могут быть неудобными для использования. Если материализованное представление использует конструкцию TO [db.]name
, то можно выполнить DETACH
представления, ALTER
для целевой таблицы и последующий ATTACH
ранее отсоединенного (DETACH
) представления.
Обратите внимание, что работа материализованного представления находится под влиянием настройки optimize_on_insert. Перед вставкой данных в таблицу происходит их слияние.
Представления выглядят так же, как обычные таблицы. Например, они перечисляются в результате запроса SHOW TABLES
.
Отсутствует отдельный запрос для удаления представлений. Чтобы удалить представление, следует использовать DROP TABLE
.
Живые представления (экспериментальные)
!!! important "Важно"
Представления LIVE VIEW
являются экспериментальной возможностью. Их использование может повлечь потерю совместимости в будущих версиях.
Чтобы использовать LIVE VIEW
и запросы WATCH
, включите настройку set allow_experimental_live_view = 1
.
CREATE LIVE VIEW [IF NOT EXISTS] [db.]table_name [WITH [TIMEOUT [value_in_sec] [AND]] [REFRESH [value_in_sec]]] AS SELECT ...
Живое представление (LIVE VIEW
) хранит результат запроса SELECT, указанного при создании, и обновляется сразу же при изменении этого результата. Конечный результат запроса и промежуточные данные, из которых формируется результат, хранятся в оперативной памяти, и это обеспечивает высокую скорость обработки для повторяющихся запросов. Живые представления могут отправлять push-уведомления при изменении результата исходного запроса SELECT
. Для этого используйте запрос WATCH.
Изменение живого представления запускается при вставке данных в таблицу, указанную в исходном запросе SELECT
.
Живые представления работают по тому же принципу, что и распределенные таблицы. Но вместо объединения отдельных частей данных с разных серверов, живые представления объединяют уже имеющийся результат с новыми данными. Если в исходном запросе живого представления есть вложенный подзапрос, его результаты не кешируются, в кеше хранится только результат основного запроса.
!!! info "Ограничения"
- Табличные функции не поддерживаются для базовой таблицы.
- Таблицы, не поддерживающие изменение с помощью запроса INSERT
, такие как Словари и Системные таблицы, а также Нормальные представления или Материализованные представления, не запускают обновление живого представления.
- Работают только запросы, сочетающие в себе частичные результаты из новых и старых данных. Живые представления не работают с запросами, требующими цельный набор данных для вычисления результата, и агрегациями с неизменяемым состоянием.
- Не работает для таблиц на движках Replicated или Distributed, вставка данных в которые происходит на разных узлах.
- Живое представление не обновляется, если используются несколько таблиц.
Используйте [WITH REFRESH](#live-view-with-refresh), чтобы принудительно обновлять живое представление с установленной периодичностью.
Для отслеживания изменений живого представления используйте запрос WATCH.
WATCH [db.]live_view
Пример:
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
CREATE LIVE VIEW lv AS SELECT sum(x) FROM mt;
Отслеживайте изменения живого представления таблицы при параллельной вставке данных в нее.
WATCH lv
┌─sum(x)─┬─_version─┐
│ 1 │ 1 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│ 2 │ 2 │
└────────┴──────────┘
┌─sum(x)─┬─_version─┐
│ 6 │ 3 │
└────────┴──────────┘
...
INSERT INTO mt VALUES (1);
INSERT INTO mt VALUES (2);
INSERT INTO mt VALUES (3);
Или используйте параметр EVENTS для получения списка изменений.
WATCH [db.]live_view EVENTS
Пример:
WATCH lv EVENTS
┌─version─┐
│ 1 │
└─────────┘
┌─version─┐
│ 2 │
└─────────┘
┌─version─┐
│ 3 │
└─────────┘
...
Используйте запрос SELECT для живого представления, как для любого другого представления. Если результат запроса кеширован, он будет возвращен немедленно, без обращения к исходным таблицам представления.
SELECT * FROM [db.]live_view WHERE ...
Принудительное обновление
You can force live view refresh using the ALTER LIVE VIEW [db.]table_name REFRESH
statement.
Можно принудительно обновить живое представление, используя выражение ALTER LIVE VIEW [db.]table_name REFRESH
.
WITH TIMEOUT
Живое представление, созданное с параметром WITH TIMEOUT
, будет автоматически удалено через определенное количество секунд с момента предыдущего запроса WATCH, примененного к данному живому представлению.
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AS SELECT ...
Если не был указано значение временного промежутка, используется значение temporary_live_view_timeout
.
Пример:
CREATE TABLE mt (x Int8) Engine = MergeTree ORDER BY x;
CREATE LIVE VIEW lv WITH TIMEOUT 15 AS SELECT sum(x) FROM mt;
WITH REFRESH
Живое представление, созданное с параметром WITH REFRESH
, будет автоматически обновляться после определенного временного промежутка, прошедшего с последнего обновления.
CREATE LIVE VIEW [db.]table_name WITH REFRESH [value_in_sec] AS SELECT ...
Если значение временного промежутка не задано, используется значение periodic_live_view_refresh
.
Пример:
CREATE LIVE VIEW lv WITH REFRESH 5 AS SELECT now();
WATCH lv
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:05 │ 1 │
└─────────────────────┴──────────┘
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:10 │ 2 │
└─────────────────────┴──────────┘
┌───────────────now()─┬─_version─┐
│ 2021-02-21 08:47:15 │ 3 │
└─────────────────────┴──────────┘
Можно сочетать параметры WITH TIMEOUT
и WITH REFRESH
с помощью AND
.
CREATE LIVE VIEW [db.]table_name WITH TIMEOUT [value_in_sec] AND REFRESH [value_in_sec] AS SELECT ...
Пример:
CREATE LIVE VIEW lv WITH TIMEOUT 15 AND REFRESH 5 AS SELECT now();
По истечении 15 секунд, представление будет автоматически удалено, если нет активного запроса WATCH
.
WATCH lv
Code: 60. DB::Exception: Received from localhost:9000. DB::Exception: Table default.lv doesn't exist..
Использование
Наиболее вероятные применения живых представлений:
- Получение push-уведомлений с изменениями представления, без необходимости отправки запроса для отслеживания изменений.
- Кеширование результатов часто используемых запросов для их получения без задержки.
- Отслеживание изменений таблицы и запуск последующих запросов
SELECT
. - Отслеживание показателей из системных таблиц с помощью периодических обновлений.
Параметры
Для управления поведением живых представлений можно использовать следующие параметры.
allow_experimental_live_view
- включить использование живых представлений. По умолчанию установлено0
.live_view_heartbeat_interval
- the heartbeat interval in seconds to indicate live query is alive. Default is15
seconds.live_view_heartbeat_interval
- периодичность индикации активности в секундах, по истечении которого представление «подаст признаки жизни». По умолчанию установлено15
.max_live_view_insert_blocks_before_refresh
- наибольшее число вставок, после которых запрос на формирование представления исполняется снова. По умолчанию количество вставок установлено64
.temporary_live_view_timeout
- interval after which live view with timeout is deleted. Default is5
seconds.temporary_live_view_timeout
- время в секундах, после которого представление удаляется. По умолчанию5
.periodic_live_view_refresh
- interval after which periodically refreshed live view is forced to refresh. Default is60
seconds.periodic_live_view_refresh
- время в секундах, по истечении которого живое представление с установленным автообновлением обновляется. По умолчанию60
.