184 похожих чатов

Всем Привет! Ребят, помогите, а то я застрял и не могу

разобраться

Есть вот такая таблица:
CREATE TABLE telemetry
(
...
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(timestamp)
PRIMARY KEY (target, schema_path, restconf_path, timestamp)
ORDER BY (target, schema_path, restconf_path, timestamp)
SETTINGS index_granularity = 32768;


и вот такой запрос:
EXPLAIN indexes = 1
SELECT
restconf_path,
toStartOfInterval(timestamp, toIntervalSecond(86400)) AS ts,
MAX(value) AS value,
FROM telemetry
WHERE (target = 'some string')
AND (schema_path LIKE 'some string%')
AND (restconf_path LIKE 'some string%')
AND (ts >= FROM_UNIXTIME(1659916800))
AND (ts <= FROM_UNIXTIME(1661040000))
GROUP BY
restconf_path,
ts

┌─explain─────────────────────────────────────────────────────────────────────────┐
│ Expression ((Projection + Before ORDER BY)) │
│ Aggregating │
│ Expression (Before GROUP BY) │
│ Filter (WHERE) │
│ SettingQuotaAndLimits (Set limits and quota after reading from storage) │
│ ReadFromMergeTree │
│ Indexes: │
│ MinMax │
│ Condition: true │
│ Parts: 39/39 │
│ Granules: 8599636/8599636 │
│ Partition │
│ Condition: true │
│ Parts: 39/39 │
│ Granules: 8599636/8599636 │
│ PrimaryKey │
│ Keys: │
│ target │
│ schema_path │
│ restconf_path │
│ Condition: and((schema_path in ['some string'...), │
│ and(and((restconf_path in ['some string'...)), │
│ (target in ['some string'...])), │
│ (schema_path in ['some string'...)))) │
│ Parts: 33/39 │
│ Granules: 42/8599636 │
└─────────────────────────────────────────────────────────────────────────────────┘


Почему запрос сканит все 8599636 гранул в MinMax и Partition индексах? Как это вылечить?

10 ответов

10 просмотров

он не сканит все гранулы, он взял 42 гранулы по primary индексу можете использовать explain estimate, он покажет количество просканированных строк

> Почему запрос сканит все 8599636 гранул в MinMax и Partition индексах? индексов у вас нет, а timestamp (по которому сделано партиционирование) не входит в where. Поэтому осталась только отсечка по первичному индексу > Как это вылечить? А надо? Но если хочется, то можно разобраться чем отличается ts от timestamp и нельзя ли их заменить или в partition by или в where

ph1lm- Автор вопроса
Boris
> Почему запрос сканит все 8599636 гранул в MinMax...

ts вычисляется с timestamp-a toStartOfInterval(timestamp, toIntervalSecond(86400)) AS ts

ph1lm- Автор вопроса
ivan
он не сканит все гранулы, он взял 42 гранулы по pr...

ох вот это я не посмотрел 👍 спасибо

ph1lm
ts вычисляется с timestamp-a toStartOfInterval(tim...

так default не гарантирует что ts вычислен из timestamp, вы можете в ts что угодно положить, вам надо просто добавить в partition by PARTITION BY (toYYYYMM(timestamp), toYYYYMM(ts ))

ph1lm- Автор вопроса
Denny [Altinity]
так default не гарантирует что ts вычислен из time...

Ts вычисляется в запросе. Partition by в объявлении таблицы. Вы предлагаете добавить materialized поле в таблицу?

ph1lm
Ts вычисляется в запросе. Partition by в объявлени...

Нет. Я предлагаю понять как работает partition pruning.

ph1lm- Автор вопроса
Denny [Altinity]
Нет. Я предлагаю понять как работает partition pr...

Я с удовольствием в этом разберусь, но по тем обрывкам информации, что вы выдаете, это будет сложно, к сожалению

ph1lm
Я с удовольствием в этом разберусь, но по тем обры...

Ну у вас партиции по одному полю а фильтруете вы по другому, кх не знает что и там и там одно и тоже https://kb.altinity.com/engines/mergetree-table-engine-family/pick-keys/ https://stackoverflow.com/questions/60142967/how-to-understand-part-and-partition-of-clickhouse?r=SearchResults&s=3%7C56.7987 Т.е.по уму надо оставить одно поле и использовать его и не хранить лишнее, если это невозможно, то можно хакнуть, партиционировать по обеим полям, т.о. чтобы партиция получалась одна, потому что в колонках одна и та же дата.

ph1lm- Автор вопроса

Похожие вопросы

Обсуждают сегодня

Какой-то там пердун в 90-х решил, что есть какая-то разная типизация. Кого вообще это волнует?
КТ315
49
void terminal_scroll() { memmove(terminal_buffer, terminal_buffer + VGA_WIDTH, buffer_size - VGA_WIDTH); memset(terminal_buffer + buffer_size - VGA_WIDTH, 0, VGA_WIDTH); ...
Егор
47
Всем привет! Подскажите, пожалуйста, в чем ошибка? Настраиваю подключение к MySQL. Либы лежат рядом с exe. Все как по "учебнику"
Евгений
16
А можете как-то проверить меня по знаниям по ассемблеру?
A A
132
Здравствуйте! У меня появилась возможность купить книгу "Изучай Haskell во имя добра!". Но я где-то слышал, что эта книга устарела. Насколько это правда??
E
22
Здравствуйте! Я вот на stepic решаю задачи на хаскеле https://stepik.org/lesson/8443/step/8?unit=1578 мой код import Data.List (isInfixOf) removing :: String -> [String] ->...
E
10
Камрады, кто тесно работал с vtv, хотел уточнить. Ширина column задаётся жёстко на этапе создания дерева или можно в рантайме ее менять программно (не мышкой)?
Ed Doc
10
да ладно ... что там неочевидного ? глянуть в исх-ки датасета и/или кверика чтобы понять в каком месте и как выполняется обращения к св-вам blablaSQL - минутное дело, даже е...
Сергей
7
Здесь для arm кто-нибудь кодит ?
Nothing
52
Всем привет, у меня есть сервер принимающий входящие HTTP подключения, как проверить, что подключение было через прокси или нет, есть какие то поля в заголовках по которым мо...
Кибер Бомж
8
Карта сайта