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

Добрый день, подскажите, а я же правильно понимаю, что индексов

в классическом понимании в кх нет?

Если так, то можно ли краткий ликбез или ссылку на то, как увеличивать перфоманс запросов, что-то я не смог ничего вменяемого найти

27 ответов

5 просмотров

Если кратко, проектируете такую архитектуру таблиц, чтобы во всех запросах в секции WHERE данные сначала отсекались по ключу партицирования, а затем по убывающей по ключу сортировки

Мне кажется документация и название движка, говорит обо всём.

правильно понимаете b-tree нет вместо него есть PRIMARY KEY по которому тоже o(log n) поиск, но он по другому устроен и есть data skip indexes которые разных типов но суть в том что они помогают быстро определить что искомых данных в заданном data part нет и его сканить не надо https://clickhouse.com/docs/en/guides/improving-query-performance/skipping-indexes/ https://clickhouse.com/docs/en/guides/improving-query-performance/sparse-primary-indexes/sparse-primary-indexes-multiple/ https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#available-types-of-indices https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#functions-support почитайте попробуйте разобраться

Slach [altinity]
правильно понимаете b-tree нет вместо него есть PR...

Пытаюсь понять skip index. Есть primary key, первая колока которого дата, потом идёт id (высокая cardinality). Пытаюсь понять, как мне помочь запросам, которые пытаются быстро найти данные с WHERE id=N. Как я понимаю, мне надо skipping index чтобы найти нужный блок и гранулы в оторых все мои id сидят. Но ведь если для каждой даты будет запись для id, то этих гранул будет много, значит эффективность будет низкой? Всё равн будет всё читать чтобы из каждого id вытащить. Что не понимаю, так это какой тип индекса выбрать. Как я понял, set не подоходит? Очевидно, что id много и cardinality будет высокий в блоках. Помогите понять как тут поступить.

Nik S.
Пытаюсь понять skip index. Есть primary key, перв...

непонятно id у вас в PRIMARY KEY включен?

Slach [altinity]
непонятно id у вас в PRIMARY KEY включен?

да, но он второй по порядку, после даты

Nik S.
да, но он второй по порядку, после даты

при высокой кардинальности id , если он у вас еще и размазано одно значение по куче дат... скип индекс вам вообще ничего не даст, только еще больше тормозить будет и вы правильно отметили почему а при при поиске по primary key будет гранулы просканены сильно больше чем одна можно снижать index_granularity у таблицы ну там 4096, 2048, 1024 и 512 и смотреть, насколько сильно больше в памяти primary key и насколько хуже hit rate в mark cache

Nik S.
Пытаюсь понять skip index. Есть primary key, перв...

skip index ускоряет только тогда, когда кол-во "отброшенных по условиям skip" партов (не обязательно кол-во, затраты на проверку "в этом парте искомых значений нет" могут быть сопоставимы с чтением парта), сильно больше от кол-ва партов найденых по условиям из primary key если у вас искомые для фильтрации данные равномерно разбросаны по всем парта, скип индекс может даже еще больше тормозить

Slach [altinity]
skip index ускоряет только тогда, когда кол-во "от...

Понял. То есть корелляция с primary key важна. А в моём случае если у каждой даты есть id, то выигрыша нет никакого.

Владислав Lazycat
А если сделать партиции по датам?

Партиции и так по датам, но это не поможет если мы делаем запрос по одному id

Nik S.
Партиции и так по датам, но это не поможет если мы...

Ну так а первым полем в PK сделать ID? P.S. тоже вот нет четкого понимания как работают индексы

Владислав Lazycat
Ну так а первым полем в PK сделать ID? P.S. тоже ...

Это можно, но как тогда быть со всеми запросами у которых date=yyymmdd? То есть все остальные запросы начнут всё сканировать.

Владислав Lazycat
Так по партициям читаться будет

но в таком случае все партиции будет читать всё равно при поиске по id=n? потому, что в них во всех будет ID фигурировать

Nik S.
но в таком случае все партиции будет читать всё ра...

Если просто по id - конечно, по индексу. Но у вас итак читается все. Но могу ошибаться. Потому что меня смущает везде фраза, что партицирование не ускоряет чтение

Владислав Lazycat
Если просто по id - конечно, по индексу. Но у вас ...

то есть при поиске по id он просто пойдёт в индекс, найдёт нужные гранулы (допустим их 3), в которых мой id есть и просто уж с ними будет работать. Если же по дате делаем поиск, то он отсеет все остальные парты и просто полностью просканит те, которые в моем диапазоне дат? Если так, до может и сработает.

Nik S.
Это можно, но как тогда быть со всеми запросами у ...

не то чтобы все... на самом деле поскольку дата монотонно возрастает... то сначала партишен прунинг будет по дате... а потом сканирование партов опять же по дате, и поскольку дата монотонно возрастает, то может и не так уж сильно медленее будет... вы проверьте

Владислав Lazycat
Если просто по id - конечно, по индексу. Но у вас ...

партицирование ускоряет запросы по которым легко отбросить партиции... то есть поле и тип данных из PARTITION BY будут в запросе...

Slach [altinity]
не то чтобы все... на самом деле поскольку дата мо...

Понял, такой вариант и попробую. У нас почти все таблицы по дате партиционированы, будет интересно узнать как же для запросов по id в будущем поступать. Спасибо!

Владислав Lazycat
А вообще попробуйте Explain indexes=1

да, гляну, когда PK поменяю. Сейчас он сначала все парты и гранулы 2 раза читает

Slach [altinity]
партицирование ускоряет запросы по которым легко о...

Если партиции созданы по типу toyyyymmdd то и в where фильтроваться тоже по этому типу нужно. Верно я понял? И вопрос а что значит буду в запросе? В блоке select?

Илья Тищенко
Если партиции созданы по типу toyyyymmdd то и в wh...

нет, не нужно по итогу будет использоваться min/max партиции, а не выражение toYYYYMMDD то есть любое условие по дате / timestamp подойдёт

Илья Тищенко
Если партиции созданы по типу toyyyymmdd то и в wh...

в блоке WHERE toYYYYMMDD возвращает UInt32 YYYY * 10000 + MM * 100 + DD там была какая то оптимизация. но я не помню где именно в доке это описано ли проверьте https://fiddle.clickhouse.com/b800acc5-0aff-4004-ad56-6cd2f68f61cb

Slach [altinity]
в блоке WHERE toYYYYMMDD возвращает UInt32 YYYY *...

как я понял если обращаться по формату создания партиции то включается оптимизатор MergeTreeWhereOptimizer и переносит фильтрацию в PREWHERE

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

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

Есть какой-нибудь для Delphi/FPC T*Compression(Decompression)Stream на базе LZ4/Zstd/любой другой быстрый(и хорошо сжимающий) алгоритм А ещё лучше в pure pascal А ещё лучше од...
notme
48
А чем вам питонисты не угодили?😂
.
79
type TObj = object procedure Init; virtual; end; TObj1 = object(TObj) procedure Init; override; end; procedure TObj1.Init; begin inherited; end; procedur...
Alexander 👋
29
Такой вопросец - есть функция function MySuperDuperConcat(const a: array of AnsiString): AnsiString; Как мне в её теле сделать вот так? Result:=Concat(a); А не грустный вариан...
notme
15
Всем привет. Поделитесь, пожалуйста, опытом. Есть форма, на которой имеется dbgrid и кнопки: добавить, редактировать, удалить. Если нет записей в dbgrid, то кнопки редактирова...
Евгений
5
Как структуру (из MSVC) в которой описаны битовые поля описать для fasm? Вот например это (fBinary...fDummy2 - это физически 1 DWORD): typedef struct _DCB { DWORD DCBlength;...
Евгений
3
Всем привет, написал код ниже, но он выдает сегфолт, в чем причина? #include <stdio.h> #include <stdlib.h> #include <string.h> struct product { char *name; float price; };...
buzz базз
86
type TExtensions<GExtender>=class function GetExtension<GEntityExtenderType>:GEntityExtenderType; end; function TExtensions<GExtender>.GetExtension<GEntityExtenderType...
zamtmn
8
Всем привет, препод задал вопрос, подскажите пожалуйста, какой адрес инкапсулирует указатель?
Свинка Пеппа
8
Вот смотрите у меня есть два стрима сейчас fs, cs: TStream; fs := TFileStream.Create('filename'); cs := TCompressionStream.Create(compression_level, fs); Я хочу сделать так: ...
notme
5
Карта сайта