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

А подскажите плиз по партициям. Создаю такую таблицу ```create table test_duration (

user_id Int64,
attempt Int64,
duration Float64,
added_at DateTime64(3) default now64()
)
engine = MergeTree
order by (user_id, attempt)
partition by toYYYYMM(added_at);```

запросы буду делать примерно такие
```select quantile(duration) from test_duration where user_id = 10 and attempt between 0 and 50000;```

т.е. всегда буду указывать user_id и attempt. Нужно ли для более эффективного поиска указывать поле, по которому партиционирование идет, added_at?

Потестил локально
```
insert into test_duration (user_id, attempt, duration, added_at)
select toInt64(number / 10000), number % 10000, number, now64() - interval number second from numbers(1000000000);
```
и как будто никакой разницы нет с фильтром по added_at и без него - количество строк считанных с диска не меняется.
А как оно в теории работает?

9 ответов

6 просмотров

так вы проверьте с фильтром added_at и без него. Это позволит не читать лишние партиции, если конечно указано поле в фильтре. А так как у вас не указано, разницы и не будет - сканирует все партиции

партиции это логическая структура и min max index внутри каждого парта... если у вас added_at в запросе в WHERE не участвует, то у вас partition pruning (отбрасывание партов из сканирование на основании значений added_at) на ранних этапах обработки запроса просто не имеет смысла ... и сканирование всегда пойдет по тем партам которые поппадают под user_id + attempt

https://youtu.be/DP7l6Swkskw?t=3777

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

Mikhail-Mayorov Автор вопроса
Denny [Altinity]
должна быть разница и большая. У вас просто что-то...

хм, до этого разницы не наблюдал, но как носом ткнули, заметил. С примером все ок. c3a2c1d2eec9 🙂 select quantile(duration) from test_duration where user_id = 10 and attempt between 0 and 5000; ┌─quantile(duration)─┐ │ 102500 │ └────────────────────┘ 1 rows in set. Elapsed: 0.032 sec. Processed 8.19 thousand rows, 196.61 KB (253.91 thousand rows/s., 6.09 MB/s.) c3a2c1d2eec9 🙂 select quantile(duration) from test_duration where user_id = 10 and attempt between 0 and 5000 and added_at between '2023-05-30 00:00:00' and '2023-05-31 00:00:00'; ┌─quantile(duration)─┐ │ 102500 │ └────────────────────┘ 1 rows in set. Elapsed: 0.005 sec. Processed 8.19 thousand rows, 262.14 KB (1.55 million rows/s., 49.52 MB/s.) на тестовом примере с added_at стабильно в 6 раз быстрее результат получаю. Т.е. лучше все же указывать поле, по которому партиционирование идет. Это ок, могу без проблем его достать. Спасибо)

Mikhail Mayorov
хм, до этого разницы не наблюдал, но как носом ткн...

пффф бред пример. Processed 8.19 thousand rows в обоих случаях у вас просто второй запрос быстрее потому что он второй и едет по кешированным данным. select count() from test_duration where added_at between '2023-05-30 00:00:00' and '2023-05-31 00:00:00'; select count() from test_duration; у вас toInt64(number / 10000) user только в одной партиции

Mikhail-Mayorov Автор вопроса
Denny [Altinity]
пффф бред пример. Processed 8.19 thousand rows в ...

разницу стабильно получаю, хоть в каком порядке выполнять. Точно кешируется? А как можно со сбросом кешей селект сделать? Каждый пользователь вряд ли будет дольше одного месяца жить - так и есть, он скорее всего всегда будет попадать в одну партицию, это ожидаемо.

Mikhail Mayorov
разницу стабильно получаю, хоть в каком порядке вы...

>Каждый пользователь вряд ли будет дольше одного месяца жить - так и есть, он скорее всего всегда будет попадать в одну партицию, это ожидаемо. в общем тогда без where added_at у вас будет драка за кеш засечек. И запросы будут выполнятся по 15сек, засечки очень медленно грузятся, это трудно показать надо нагенерить много данных, чтобы размер засечек стал больше чем 5ГБ.

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

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

Какой-то там пердун в 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
Карта сайта