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

Друзья, доброго времени суток! Такой вопрос: Мы используем BI продукт FineBI, внутри

которой есть какая-то своя китайская колоночная БД.
Грузим в FineBi датасет относительно небольшой (20 млн. строк) - получаем 13.1 GB.
Грузим такой же датасет в CH - там он весит 7.1 GB.

Обрадовавшись, я подумал, что так будет и со всеми датасетами. Но когда загрузил датасет с большим числом строк (200+ млн. строк), получил обратный эффект, размер датасета в CH больше в 2 раза, чем в китайской БД.

Стал смотреть на размер отдельных столбцов в мегабайтах и заметил такую штуку.
Вот запрос к маленькой табличке и информация по столбцу brand.
SELECT
"column"
, "type"
, "column_bytes_on_disk" / 1024 / 1024 AS "column_bytes_on_disk_mb"
, "rows"
FROM system.parts_columns
WHERE 1=1
AND "table" = 'mart_rx_prescriptions_with_category'
AND "column" = 'brand'
Результат следующий:
column|type |column_bytes_on_disk_mb|rows |
------+------+-----------------------+--------+
brand |String| 41.45439147949219|22774591|
brand |String| 1.4867048263549805| 807546|

Теперь аналогично для большой таблицы:
SELECT
"column"
, "type"
, "column_bytes_on_disk" / 1024 / 1024 AS "column_bytes_on_disk_mb"
, "rows"
FROM system.parts_columns
WHERE 1=1
AND "table" = 'mart_so_regions__dbt_backup'
AND "column" = 'brand'
Результат следующий:
column|type |column_bytes_on_disk_mb|rows |
------+------+-----------------------+--------+
brand |String| 128.24172687530518|14024704|
brand |String| 129.45257377624512|14155776|
brand |String| 129.4500217437744|14155776|
brand |String| 129.46148300170898|14155573|
brand |String| 107.90291976928711|11796480|
brand |String| 21.57454204559326| 2359296|
brand |String| 107.2841968536377|11730944|
brand |String| 21.582709312438965| 2359296|
brand |String| 21.567069053649902| 2359296|
brand |String| 21.577152252197266| 2359296|
brand |String| 20.982440948486328| 2293760|

Так вот теперь вопрос - почему, по сути, одно и то же стринговое поле, которое содержит одни и те же значения с примерно одной и той кардинальностью в первом случае занимает 41 мегабайт на 22 млн. строк и 128 мегабайт на 14 млн. строк во втором случае?

7 ответов

124 просмотра

сжатие зависит от сортировки, если значение в колонке лежит в рандомном порядке, сжатие будет плохое если колонка в ORDER BY, значит одинаковые значения лежат рядом на диске, значит сжимаются данные в разы лучше ну и запрос вы странно делаете, сделайте группировку по всем партам и посчитайте размер 1 строки SELECT column, type, sum(column_bytes_on_disk) AS compressed, formatReadableSize(compressed) AS human, sum(column_data_uncompressed_bytes) AS uncompressed, uncompressed / compressed AS ratio, sum(rows) AS row_count, compressed / row_count AS size_per_row FROM system.parts_columns WHERE (table = '...') AND (column = '...') AND active GROUP BY column, type ORDER BY compressed ASC

unhingedlunatic- Автор вопроса
Konstantin Ilchenko
сжатие зависит от сортировки, если значение в коло...

Спасибо! Так еще наглядней это видно) column|type |compressed|human |uncompressed|ratio |row_count|size_per_row | ------+------+----------+----------+------------+-----------------+---------+-----------------+ brand |String| 767340495|731.79 MiB| 1584925202|2.065478379321034| 80019253|9.589448366882404| column|type |compressed|human |uncompressed|ratio |row_count|size_per_row | ------+------+----------+---------+------------+------------------+---------+------------------+ brand |String| 45027003|42.94 MiB| 457261697|10.155277201105301| 23582137|1.9093690703264086| 9.6 vs 1.9 на строку, кошмар просто. В самих запросах или при создании таблицы ни там ни там сортировка не указывалась, но, видимо, так исторически сложилось, что в первой таблице реально бренд чаще за подряд идет одинаковый, а во второй как-то в разнобой. Или это бы не помогло без явной сортировки? Тогда еще такой вопрос: допустим у меня есть два поля "Дата" и "Бренд". Сделав сортировку по Дате и Бренду одновременно (но Дата первая в сортировке) и просто по полю Бренд, в первом случае столбец Бренд будет занимать больше места? Т.е. я обречен на какие-то компромиссы всегда, типа сортирую по Бренду, уменьшаю размер этого столбца, но увеличиваю размер столбца Дата таким образом.

unhingedlunatic
Спасибо! Так еще наглядней это видно) column|type ...

> Т.е. я обречен на какие-то компромиссы всегда Это вообще всегда в разработке, приходится везде выбирать Порядок колонок обычно зависит от кардинальности Чем меньше уникальных значений тем раньше стоит ставить в ключ сортировки, тогда следующая колонка будет лежать "лучше" Ну и частоту фильтрации по колонке стоит учитывать, если у вас 100% запросов используют какую-то колонку, то стоит её тоже поближе к началу двигать > Или это бы не помогло без явной сортировки? Ну если вы в одном случае всталяете 1млн строк по одному бренду, а во втором случае в разнобой, то может быть и без сортировки разница.

unhingedlunatic- Автор вопроса
Konstantin Ilchenko
> Т.е. я обречен на какие-то компромиссы всегда Эт...

Константин, спасибо большое) стало понятней, завтра попробую поиграться с сортировкой

unhingedlunatic
Константин, спасибо большое) стало понятней, завтр...

если уникальных брендов не много(до 10 тысяч значений) можно ещё попробовать LowCardinality(String) тип попробовать, должно ещё меньше места занимать

unhingedlunatic- Автор вопроса
Konstantin Ilchenko
если уникальных брендов не много(до 10 тысяч значе...

Их как-раз плюс минус 10 тысяч 😁 но у меня другие поля есть, например, города и специальности, можно туда, наверное, это попробовать прикрутить, их то совсем мало

unhingedlunatic
Их как-раз плюс минус 10 тысяч 😁 но у меня другие ...

Тогда вполне возможно имеет смысл использовать lowCardinality

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

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

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта