Добрый день.
Помогите пожалуйста разобраться в MATERIALIZED VIEW
Проблама в том, выполнятеся фул скан всех партов представления, но мне бы хотелось этого избежать
сырые данные лежат подобным образом
CREATE TABLE IF NOT EXISTS v1_fts.local_ids
ON CLUSTER cluster
(
date
Date,
id
UInt64,
words
Array(UInt64)
)
ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/v1_fts/local_ids',
'{replica}')
PARTITION BY date
ORDER BY (date, id)
SETTINGS index_granularity = 8192;
распределеённая таблица
CREATE TABLE IF NOT EXISTS v1_fts.ids
ON CLUSTER cluster
(
date
Date,
id
UInt64,
words
Array(UInt64)
)
ENGINE Distributed(cluster, v1_fts, local_ids, id);
Я бы хотел исполнять запрос подобного вида:
SELECT date, id
FROM
(
SELECT DISTINCT
date,
id
FROM v1_fts.ids
PREWHERE date = '2021-03-18' AND words hasAll(words, [16015426228996655908,1584244114596650083])
ORDER BY id
LIMIT 0,10);
но это фулскан из-за того что индекс не по words
делаю новую таблицу
CREATE TABLE v1_fts.local_words
ON CLUSTER cluster
(
date
Date,
word
UInt64,
words
Array(UInt64),
id
UInt64
) ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/v1_fts/local_words', '{replica}')
PARTITION BY tuple()
ORDER BY (date, word, words, id);
и mat view для нее
CREATE MATERIALIZED VIEW IF NOT EXISTS v1_fts.words_mv
ON CLUSTER cluster
TO v1_fts.local_words
AS
SELECT date,
word,
words
FROM v1_fts.local_ids
ARRAY JOIN words AS word
GROUP BY (date, word, words, id);
и распределенная таблица для words
CREATE TABLE IF NOT EXISTS v1_fts.words
ON CLUSTER cluster
(
date
Date,
word
UInt64,
words
Array(UInt64),
id
UInt64,
) ENGINE = Distributed(cluster, v1_fts, local_words, word);
заливаю новые данные в распределенную таблицу v1_fts.words небольшими кусками по 10000 строк, общее количкство строк порядка десяти миллинов.
выплняю модицированный запрос
SELECT date, id
FROM
(
SELECT DISTINCT
date,
id
FROM v1_fts.words
PREWHERE date = '2021-03-18' AND word IN (16015426228996655908,1584244114596650083) AND hasAll(words, [16015426228996655908,1584244114596650083])
ORDER BY id
LIMIT 0,10);
по логу я вижу, что выполнятеся фулскан таблицы v1_fts.local_words на всех шардах
Подскажите пожалуйста как организовать даные и избежать фулскан таблицы v1_fts.local_words в этом кейсе?
Сам себе отвечу на вопрос. Вдруг кому то поможет.
Мне помог вот этот документ
https://den-crane.github.io/Everything_you_should_know_about_materialized_views_commented.pdfесли хочешь реорганизовать данные, то нужно "натравить" материализованное представление на распределённую таблицу, а не на локальную, тогда данные будут правильно организованы.
CREATE MATERIALIZED VIEW IF NOT EXISTS v1_fts.words_mv
ON CLUSTER cluster
TO v1_fts.words
AS
SELECT date,
word,
words
FROM v1_fts.ids
ARRAY JOIN words AS word
GROUP BY (date, word, words, id);