Сэмплирование данных
Иногда ответ «примерно» по 10% данных в десять раз быстрее точного по всем.
Сэмплирование (sampling) — вычисление приблизительного результата по детерминированной части данных вместо всей таблицы ради скорости.
Зачем считать «примерно»
Для многих задач точность до последней цифры не нужна. «Сколько примерно уникальных пользователей зашло» или «какова приблизительная конверсия» — для дашборда хватит оценки с погрешностью в доли процента, зато в разы быстрее. Сэмплирование читает, скажем, каждую десятую строку и масштабирует результат.
Как это включить
Сэмплирование задаётся на этапе создания таблицы — через SAMPLE BY с колонкой из первичного ключа (обычно хешированной), а в запросе используется SAMPLE:
CREATE TABLE events
(
event_date Date,
user_id UInt32,
value Float64
)
ENGINE = MergeTree
ORDER BY (event_date, intHash32(user_id))
SAMPLE BY intHash32(user_id);
-- Запрос по 10% данных
SELECT count() * 10 AS approx_total
FROM events
SAMPLE 0.1;Здесь SAMPLE 0.1 берёт ~10% данных; чтобы оценить полное число, результат домножают на 10.
Важное свойство: детерминированность
Сэмплирование в ClickHouse стабильно: одна и та же выборка попадает в семпл всегда. Поэтому, если семплировать по user_id, в выборку попадут все события одних и тех же пользователей. Это позволяет корректно считать показатели вроде «событий на пользователя» — пользователь либо целиком в выборке, либо целиком вне её.
Что можно и нельзя оценивать
| Метрика | Сэмплирование |
| Доли, конверсии, средние | оценивается хорошо |
| Приблизительные суммы/счётчики | оценивается (масштабированием) |
| Точные финансовые итоги | не годится — нужна точность |
| Редкие события («хвосты») | опасно — могут не попасть в семпл |
Иллюстрация масштабирования
Покажем идею оценки полного объёма по семплу (чистый Python):
sample_fraction = 0.1
count_in_sample = 12345 # столько строк попало в 10%-семпл
estimated_total = count_in_sample / sample_fraction
print("В семпле строк:", count_in_sample)
print("Оценка всего:", int(estimated_total))Вывод:
В семпле строк: 12345 Оценка всего: 123450
Как работает под капотом
ClickHouse использует SAMPLE BY-колонку как «координату»: значение хеша делит пространство ключей, и SAMPLE 0.1 отбирает первую десятую часть этого пространства. Поскольку отбор идёт по детерминированному хешу, он стабилен и читает только соответствующие гранулы — отсюда ускорение.
Частые ошибки
- Сэмплировать финансы. Для точных денежных сумм приближение недопустимо.
- Забыть масштабировать. Сумма/счётчик по семплу — это доля; её нужно домножить на обратную долю семпла.
- Искать редкие события в семпле. Редкие случаи могут вовсе не попасть в выборку.
Итоги
- Сэмплирование считает приблизительно по части данных — ради скорости.
- Требует
SAMPLE BYв схеме; в запросе —SAMPLE долю. - Выборка детерминирована и группирует все строки одного ключа вместе.
- Подходит для долей/средних, но не для точных финансов и редких событий.