В предыдущем ответе предлагалось два возможных метода: приблизительный подсчет и size(collect_set(...))
. У обоих есть проблемы.
Если вам нужен точный подсчет, который является основной причиной использования COUNT (DISTINCT ...) в больших данных, приблизительный подсчет не подойдет. Кроме того, приблизительный подсчет фактических коэффициентов ошибок может значительно отличаться для небольших данных.
size(collect_set(...))
может привести к значительному замедлению обработки больших данных, поскольку в нем используется изменяемый Scala HashSet
, что довольно медленная структура данных. Кроме того, вы можете иногда получать странные результаты, например, если вы выполняете запрос через пустой фрейм данных, потому что size(null)
выдает противоинтуитивное значение -1. Собственный отчетливый подсчет Spark выполняется быстрее по ряду причин, главная из которых заключается в том, что ему не нужно создавать все подсчитанные данные в массиве.
Типичный подход к решению этой проблемы заключается в самостоятельном присоединиться. Вы группируете по любым столбцам, которые вам нужны, вычисляете отдельное число или любую другую статистическую функцию, которую нельзя использовать в качестве оконной функции, а затем присоединяетесь к исходным данным.