Как посчитать перцентили в SQL
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем это знать
Среднее время загрузки страницы 200ms — звучит ок, пока не увидишь, что P95 = 3 секунды. Среднее скрывает хвосты, перцентили — показывают. Любой SRE-dashboard и любой performance-отчёт содержат P50, P90, P95, P99.
На собесах: «рассчитай P95 response_time по серверам» — классическая middle-задача.
Что такое перцентиль
P90 = значение, ниже которого лежит 90% данных. P95 — 95%, P99 — 99% (tail).
P50 = медиана.
PERCENTILE_CONT (Postgres, MSSQL)
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY response_ms) AS p50,
PERCENTILE_CONT(0.9) WITHIN GROUP (ORDER BY response_ms) AS p90,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY response_ms) AS p95,
PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY response_ms) AS p99
FROM requests;Одним запросом. _cont интерполирует между соседними значениями.
ClickHouse
SELECT
quantile(0.5)(response_ms) AS p50,
quantile(0.9)(response_ms) AS p90,
quantile(0.95)(response_ms) AS p95,
quantile(0.99)(response_ms) AS p99
FROM requests;Быстро, approximate (но точно для практики).
Exact вариант:
SELECT quantileExact(0.95)(response_ms) FROM requests;По группам
Perсентили по endpoint:
SELECT endpoint,
PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY response_ms) AS p95
FROM requests
GROUP BY endpoint
ORDER BY p95 DESC;Видны endpoints с worst latency.
MySQL (до 8.0)
Через ROW_NUMBER или window functions в 8.0+:
WITH ranked AS (
SELECT response_ms,
ROW_NUMBER() OVER (ORDER BY response_ms) AS rn,
COUNT(*) OVER () AS n
FROM requests
)
SELECT response_ms AS p95
FROM ranked
WHERE rn = CEIL(n * 0.95);PERCENTILE_DISC
Возвращает существующее значение (не интерполирует):
PERCENTILE_DISC(0.95) WITHIN GROUP (ORDER BY response_ms)На практике почти эквивалентно _cont на больших данных.
Не-стандартные перцентили
P99.9 (тяжёлый tail):
PERCENTILE_CONT(0.999) WITHIN GROUP (ORDER BY response_ms)Нужно много данных (иначе один outlier = P99.9).
HDR Histograms
Для реального high-scale логирования latency используют HDR-гистограммы, не SQL. ClickHouse quantileTDigest — approximate, но быстро.
На собесе
«Как посчитать P95 response time по endpoint?».
Идеальный ответ: PERCENTILE_CONT + GROUP BY endpoint. Упомянуть quantile в ClickHouse для fast approximate.
Связанные темы
FAQ
Почему не среднее?
Среднее скрывает outliers. Перцентили показывают распределение.
Разница quantile и quantileExact?
Exact точный, но медленный. Approximate — быстрый, точность достаточна для мониторинга.
Как визуализировать?
Box plot или series P50/P90/P95/P99 — стандарт.
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.