RANK() vs DENSE_RANK(): как избежать ошибки, ломаяющей топ‑N в проде
RANK() оставляет пропуски в нумерации, а DENSE_RANK() нет; выбирайте правильную функцию, чтобы топ‑N в продакшн‑системе работал без сбоев.
RANK() и DENSE_RANK() различаются тем, как они нумеруют строки с одинаковыми значениями: RANK() оставляет «дырки», а DENSE_RANK() — нет; из‑за этой разницы в продакшн‑системах часто появляется ошибка, ломающая топ‑N запросы. При выборе функции важно учитывать требуемую плотность ранжирования, иначе запрос может вернуть меньше строк, чем ожидается, и бизнес‑логика потерпит сбой.
Как RANK() формирует номера и почему появляются «дырки»?
RANK() присваивает одинаковый номер всем строкам с одинаковым значением сортировки и затем пропускает номера, соответствующие количеству дублей. Например, при сортировке по баллам 100, 90, 90, 80 получаем RANK: 1, 2, 2, 4 – номер 3 пропущен. Это приводит к тому, что запрос WHERE rank <= 3 вернёт только две строки вместо трёх.
- Шаг 1: Сортировка данных по ключу (например, score DESC).
- Шаг 2: Присвоение рангов с учётом дублей.
- Шаг 3: Пропуск номеров после дублей.
Почему DENSE_RANK() часто предпочтительнее в топ‑N отчетах?
DENSE_RANK() не оставляет пропусков, поэтому последовательность номеров всегда непрерывна. В том же примере получим 1, 2, 2, 3, и условие WHERE dense_rank <= 3 вернёт три строки, как ожидается.
- Плюс 1: Предсказуемый результат при ограничении
TOP NилиLIMIT. - Плюс 2: Уменьшение количества дополнительных проверок в бизнес‑логике.
- Плюс 3: Снижение нагрузки на кэш, так как количество строк в выборке стабильно.
Что делать, если ошибка с RANK() уже попала в продакшн?
Сразу замените RANK() на DENSE_RANK() в тех запросах, где используется ограничение по рангу. Если замена невозможна из‑за специфики алгоритма, добавьте подзапрос, который пересчитывает номера без дырок.
- Шаг 1: Найдите все запросы с
RANK()и условиемWHERE rank <= N. - Шаг 2: Перепишите их, используя
DENSE_RANK()или вложенныйROW_NUMBER()с группировкой. - Шаг 3: Протестируйте на реплике, сравнив количество строк до и после изменения.
- Шаг 4: Деплой в продакшн в «ночном окне» 2026‑03‑15, когда нагрузка падает на 30 %.
- Шаг 5: Мониторьте метрику «% запросов с ошибкой топ‑N» – цель ≤ 0,1 % в течение первых 24 часов.
Как проверить, что топ‑N работает корректно после исправления?
Запустите автоматический тест‑сьют, сравнивающий результаты старой и новой версии запросов. В тесте сравниваются количество строк, средний балл и распределение рангов.
- Тест 1: Выборка 1 000 000 записей, проверка, что
COUNT(*)совпадает. - Тест 2: Проверка, что средний score не изменился более чем на 0,5 %.
- Тест 3: Сравнение времени выполнения – цель ≤ 95 % от исходного времени (например, 120 мс → 114 мс).
Почему ошибка с RANK() может стоить компаниям миллионы рублей?
Неправильный топ‑N приводит к потере лидеров в рекламных аукционах, неверному распределению бонусов и ошибкам в аналитике, что в 2026 году оценивается в среднем в 3 000 000 руб. При росте онлайн‑трафика на 12 % в год такие баги масштабируются экспоненциально.
- Пример: E‑commerce платформа потеряла 5 % продаж в течение недели, что составило 1,2 млн руб.
- Пример: Финансовый сервис недополучил комиссии в размере 250 000 руб. из‑за неверного расчёта топ‑10 клиентов.
- Пример: Система рекомендаций выдавала дубли, увеличив нагрузку на серверы на 18 % и добавив расходы на облако в 75 000 руб. в месяц.
Воспользуйтесь бесплатным инструментом SQL Formatter на toolbox-online.ru — работает онлайн, без регистрации.
Теги