Набор данных состоит из ежедневных временных рядов с ~ 1000 уникальных групп с История 125 лет.
Я не могу управлять всем набором данных в одном паркете, поэтому я выбрал Delta Lake в качестве метода хранения. < /p>
Прямо сейчас я пытаюсь Определите наилучшую стратегию разделения, чтобы сбалансировать производительность запроса (!), Управление файлами и эффективность записи. p>
- Группа: String (~ 1000 уникальных значений). < /li>
Дата: ежедневно с 1900 по 2025 год. < /li> 5 столбцов числового значения. < /li>
Хранится в таблице Delta. < /li>
Расчетный размер: 2–5 ГБ. >
< /ul>
Ежедневные подъемы: < /p>
Небольшой набор данных (1–30 дней) объединяется ежедневно, Еженедельно или ежемесячно в таблицу Delta. -Корирование в группе и дате. - вакуум для удаления ненужных файлов.
Я рассматриваю два варианта: < /p>
Разделение по году: < /p>
Лучше для постепенных обновлений и удалений. > Разделение к десятилетию: < /p>
уменьшает разделы до 13, что означает меньше небольших файлов. Обновления и удаления.
Тем не менее, я обычно фильтрую дату при чтении набора данных, а не на год или десятилетие, поэтому запрос по разделу в этом случае не полезен. < /p>
Мои основные вопросы, есть ли лучше Стратегии разделения для Delta Lake в моем случае?
Как я могу эффективно управлять размерами файлов без жертвы запрашиваемости? Одиночный большой паркетный файл: < /p>
import os
import shutil
import psutil
from pathlib import Path
from datetime import date, timedelta
import polars as pl
from deltalake import DeltaTable
def generate_data(ngroups, ndates, ncols=5, start=date(1900, 1, 1), value=1.0, eager=True) -> pl.DataFrame | pl.LazyFrame:
groups = pl.LazyFrame({'group': pl.arange(1, ngroups+1, dtype=pl.Int64, eager=True).cast(pl.String)})
dates = pl.LazyFrame({'date': pl.date_range(start, start+timedelta(days=ndates-1), "1d", eager=True)})
lf = (
groups.join(dates, how='cross')
.with_columns(
[pl.lit(i*value, dtype=pl.Float64).alias(f'val_{i}') for i in range(1, ncols+1)])
)
return lf.collect() if eager else lf
print('Generating initial "large" dataset...')
df = generate_data(ngroups=1000, ndates=125*365, value=1.0, eager=True)
print(df.tail(3))
# ┌───────┬────────────┬───────┬───────┬───────┬───────┬───────┐
# │ group ┆ date ┆ val_1 ┆ val_2 ┆ val_3 ┆ val_4 ┆ val_5 │
# │ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
# │ str ┆ date ┆ f64 ┆ f64 ┆ f64 ┆ f64 ┆ f64 │
# ╞═══════╪════════════╪═══════╪═══════╪═══════╪═══════╪═══════╡
# │ 1000 ┆ 2024-11-28 ┆ 1.0 ┆ 2.0 ┆ 3.0 ┆ 4.0 ┆ 5.0 │
# │ 1000 ┆ 2024-11-29 ┆ 1.0 ┆ 2.0 ┆ 3.0 ┆ 4.0 ┆ 5.0 │
# │ 1000 ┆ 2024-11-30 ┆ 1.0 ┆ 2.0 ┆ 3.0 ┆ 4.0 ┆ 5.0 │
# └───────┴────────────┴───────┴───────┴───────┴───────┴───────┘
size = df.estimated_size("gb")
memory = psutil.virtual_memory().total/1024**3
print(f' size/memory => {size:.3}gb/{memory:.3}gb => {int(100*size/memory)}%')
# size/memory => 1.99gb/15.5gb => 12%
print('Saving initial "large" "dataset to delta table...')
delta_path = Path('./table/').resolve() #
Подробнее здесь: https://stackoverflow.com/questions/794 ... n-a-laptop