GH GambleHub

Индексация аналитических хранилищ

1) Зачем индексация iGaming-платформе

Скорость аналитики: отчеты по GGR/NET, конверсиям, RG/AML и A/B-экспериментам укладываются в SLA.
Стоимость: меньше сканируемых байт → ниже счет за вычисление/склад.
Надежность: стабильные p95/p99 латентности дашбордов и API метрик.
Масштаб: десятки брендов/рынков/PSP/провайдеров без «full scan» адской стоимости.

2) Модель нагрузок (прежде чем индексировать)

Факты: `payments`, `game_rounds`, `sessions`, `bonus_events`.
Измерения: `dim_user` (без PII), `dim_provider`, `dim_psp`, `dim_country`.
Запросы: «последние N дней», агрегации по `brand/country/provider/psp`, фильтры по статусовому полю, join’ы по surrogate-keys, поиск по JSON-атрибутам (метод платежа, устройство), top-K/percentile.

Выбираем индексы, исходя из селективности, кардинальности и частоты использования.

3) Типы индексов и когда их брать

3.1 Классика

B-tree: равенство/диапазоны по высокоселективным колонкам (`user_surrogate_id`, `occurred_at`, `amount`).
Hash: чистое равенство; реже в аналитике (против диапазонов слаб).
Bitmap: низкая кардинальность и частые соединенные фильтры (`country`, `kyc_level`, `rg_state`, `brand`). Отличны для суммирования масок.

3.2 Columnar-специфика

Min-max (data skipping): автоматические статистики «минимум/максимум» в паркет-страйпах/частях → движок пропускает блоки. Работает лучше при сортировке по фильтруемым полям.
Bloom-индексы: быстрые вероятностные тесты принадлежности значения в блоке (полезны для `user_id`, `transaction_id`, `psp`).
BRIN (Block Range Index): дешевые «указатели» на диапазоны блоков, если данные естественно упорядочены (время). Дешево, но эффективно для time-series.

3.3 Продвинутые/специализированные

GiST/GIN (инвертированные): JSON/arrays/текст, фильтры по вложенным атрибутам (`metadata.method = 'Papara'`, `device.os in [...]`).
Join/Projection (ClickHouse/MPP): материалы для ускорения join/agg (pre-join key хранится рядом с фактом, предварительные агрегации).
Векторные (ANN): поиск похожих эмбеддингов (рекомендации/антифрод-поведение) — IVF/HNSW/Flat как «индекс ближайших соседей».
З-упорядочивание/Z-order (lakehouse/Databricks) / Cluster keys (Snowflake) / ORDER BY (ClickHouse): многомерная кластеризация данных на диске для лучшего data skipping.

4) Партиционирование, сортировки, кластеризация

Партиции (date/country/brand): крупные (день/неделя), чтобы избежать «проклятия малых файлов». Выбираем поля с высокой селективностью в WHERE/права доступа.
Сортировка внутри партиции: `ORDER BY (occurred_at, brand, psp)` или Z-order по `(brand, country, provider)` — так min-max и bloom отрабатывают лучше.
Cluster/Recluster: периодическая перекластеризация для поддержания локальности.
TTL и ретеншн: автоматическое удаление старых партиций/сегментов.

5) Материализованные представления и проекции

MV для горячих срезов: `payments_7d_by_brand_psp`, `rounds_1d_by_provider`. Поддерживаем инкрементально (streaming upserts).
Проекции (ClickHouse) / Aggregate tables: предварительные группировки, roll-up уровни (час→день→неделя).
Кэш результатов: query result cache/warehouse result cache для повторяемых дашбордов (валидируем по токену запроса и свежести данных).

6) Полуструктурированные данные (JSON/VARIANT)

Индексы по путям: инвертированные/GIN-индекс на json-путях (`$.device.os`, `$.psp.details.method`).
Материализация важных атрибутов в колонки: для стабильных фильтров (метод платежа, устройство, версия приложения).
Статистики по ключам: сбор дистрибуций для селективного плана.

7) Озера данных: Iceberg / Delta / Hudi

Манifest-индексы: метаданные о паркет-файлах (min-max, null-count, bloom) → partition pruning + file skipping.
Компакция/объединение файлов: регулярный merge небольших файлов в «оптимальный» размер (128–1024 МБ).
Clustering/Z-order: переупаковка файлов для коррелирующих полей (например, `brand,country,occurred_at`).
Delete/Update индексы: позиционные делты и bloom для ускорения merge-on-read.

8) Как выбирать индексы: практический чек-лист

1. Соберите топ-N запросов (90% нагрузки) → поля фильтров/join/group.
2. Для каждого поля оцените селективность `sel = 1 - distinct(value)/rows` и кардинальность.
3. Партиция по времени + 1–2 измерения со стабильными фильтрами/доступами.
4. Сортировки/кластер keys согласовать с фильтрами и join-ключами.
5. Добавьте bloom для точечных id, bitmap для низкой кардинальности.
6. Горячие агрегации → MV/проекции.
7. JSON-пути → инвертированные индексы + материализация.
8. На озерах — компакция и clustering по расписанию.
9. Введите SLO: p95-латентность, сканируемые байты/запрос, доля skipped data.

9) Поддержка и обслуживание

ANALYZE/статистики: обновляйте кардинальности и гистограммы; иначе оптимизатор «слепой».
VACUUM/OPTIMIZE/RECLUSTER: дефрагментация и перекластеризация.
Мониторинг использования индексов: «covering rate», «unused index list», «bytes scanned / bytes skipped».
Авто-советчики: периодические рекомендации по кластер-ключам и сортировкам на основании query log.
Тесты регрессий: перед деплоем новых ключей — сравнение профиля запросов и стоимости.

10) Метрики и SLO индексации

Технические: p95/p99 latency, scanned bytes/query, skipped bytes %, files touched, cache hit-rate.
Экономика: $/запрос, $/дашборд, $/TB скана.
Операции: время компакции, очередь перекластеризации, доля «малых файлов».
Качество планов: доля запросов, использующих индексы/проекции, точность кардинальностей.

11) Кейсы iGaming (готовые рецепты)

11.1 Платежи/PSP: падения/отказы

Партиция: `by day`. Сортировка: `(brand, country, occurred_at)`.
Bloom: `transaction_id`, `user_id`. Bitmap: `psp`, `status`.
MV: `payments_7d_by_brand_psp(status, declines)`.
Результат: p95 ↓ с 8.2s до 1.1s, scanned bytes ↓ на 87%.

11.2 Игровые раунды: провайдер/игра

Z-order / ORDER BY: `(provider, game_id, occurred_at)`.
Projection/agg: `rounds_1d_by_provider_game`.
BRIN (если Postgres-подобное хранилище): по `occurred_at`.
Результат: топ-K игр/час — sub-second на горячем кэше.

11.3 RG/AML: события ограничений/самоисключений

Bitmap: `rg_state`, `kyc_level`. JSON-path GIN: `$.reason`.
MV: «активные ограничения за 30 дней» + материализация user-уровня без PII.
Результат: быстрые выборки для комплаенса без full scan миллиарда событий.

11.4 Антифрод: маршруты и устройства

Материализация JSON→колонки: `device.os`, `device.model`, `payment.method`.
Bloom: `graph_device_id`. Cluster: `(brand, country, device.os)`.
Векторный индекс: эмбеддинги «поведение депозитов за 7д» → быстрый k-NN для похожих аномалий.

12) Безопасность и приватность

Zero-PII в индексируемых полях и логах планов.
Шифрование на диске: индексы/статистики шифруются так же, как данные.
K-анонимность агрегатов: MV/проекции публикуют только группы ≥N.
Geo/tenant-изоляция: партиции/ключи включают `brand/country/license`.
Legal Hold: индексы/манивесты тоже попадают в «заморозку».

13) Анти-паттерны

Индексировать «все подряд» → взрыв объема и write-amplification.
Мелкие партиции (час/минуты) → шторм планок и «малые файлы».
Ключи сортировки, не совпадающие с фильтрами → нулевой data skipping.
Отсутствие статистик → плохие планы, full scan.
JSON без путевых индексов и без материализации «горячих» атрибутов.
Игнор компакции и recluster → деградация через 2–4 недели.

14) Шаблоны (готово к использованию)

14.1 Политика кластеризации/индексации (YAML)

yaml dataset: gold. payments partition_by: ["date"]
order_by: ["brand","country","occurred_at"]
indexes:
bloom: ["transaction_id","user_surrogate_id"]
bitmap: ["psp","status","rg_state"]
materialized_views:
- name: mv_payments_7d_brand_psp group_by: ["brand","psp","status"]
window: "7d"
slo:
p95_latency_ms: 1200 scanned_bytes_per_query_max_mb: 256 maintenance:
compact_small_files: true recluster_cron: "0 /6  "
privacy:
pii_in_index: false

14.2 План компакции озера (Iceberg/Delta)

yaml compaction:
target_file_size_mb: 512 small_file_threshold_mb: 64 zorder_by: ["brand","country","occurred_at"]
run_every: "PT6H"
max_concurrency: 4

14.3 Индексы для JSON-полей

sql
-- GIN/inverted index on device attributes
CREATE INDEX idx_device_json ON gold. sessions
USING GIN ((device_json));
-- Materialization of critical pathways
ALTER TABLE gold. sessions ADD COLUMN device_os TEXT;
UPDATE gold. sessions SET device_os = device_json->>'os';
CREATE BITMAP INDEX idx_device_os ON gold. sessions(device_os);

14.4 SLO мониторинга индексов

yaml monitoring:
skipped_bytes_share_min: 0. 70 index_usage_rate_min: 0. 85 stats_freshness_max_hours: 24 small_files_share_max: 0. 10

15) Дорожная карта внедрения

0–30 дней (MVP)

1. Сбор топ-N запросов и профилей сканирования.
2. Партиционирование по дате + сортировки, согласованные с фильтрами.
3. Включить data skipping (min-max) и bloom для id-полей.
4. Один MV для «горячей» метрики (payments 7d).
5. Дашборд SLI: p95, scanned bytes, skipped share, small files.

30–90 дней

1. JSON-пути: инвертированные индексы + материализация.
2. Озеро: компакция и Z-order/clustering по 2–3 ключам.
3. Автосоветчик ключей/проекций; регулярный ANALYZE.
4. Пересмотр партиций (day→week) там, где «малые файлы».

3–6 месяцев

1. Каталог MV/проекций с версионированием и SLA.
2. Векторные индексы для рекомендаций/антифрода.
3. Единая политика SLO и бюджетов $/запрос; алерты деградаций.
4. Аудит приватности индексов, geo/tenant-изоляция.

16) RACI

Data Platform (R): партиции/индексы/компакции, авто-советчики, мониторинг.
Analytics/BI (R): MV/проекции под дашборды, профилирование запросов.
Domain Owners (C): критерии «горячих» срезов и фильтров.
Security/DPO (A/R): приватность, PII-политики, geo/tenant-ключи.
SRE/Observability (C): SLO/алертинг, капасити для компакций.
Finance (C): бюджеты $/запрос и экономия от индексов.

17) Связанные разделы

Схемы данных и их эволюция, Валидация данных, DataOps-практики, Анализ аномалий и корреляций, API аналитики и метрик, Кластеризация данных, Снижение размерности, MLOps: эксплуатация моделей.

Итог

Индексация аналитического хранилища — это стратегия, а не «создать индекс на все». Правильные партиции и сортировки, data skipping и bloom, продуманные MV/проекции и регулярная компакция дают быстрые и предсказуемые запросы при контролируемой стоимости и без риска для приватности. Для iGaming это означает оперативные решения по платежам, провайдерам и RG/AML — в пределах SLA и бюджета.

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

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