Merge pull request #1557 from BayoNet/master

`anyHeavy` and `topK` functions are described.
This commit is contained in:
alexey-milovidov 2017-12-01 19:15:29 +03:00 committed by GitHub
commit 638c5d53c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 138 additions and 81 deletions

View File

@ -1,14 +1,15 @@
<a name="aggregate_functions"></a>
Агрегатные функции
==================
# Агрегатные функции
Агрегатные функции работают в [привычном](http://www.sql-tutorial.com/sql-aggregate-functions-sql-tutorial) для специалистов по базам данных смысле.
ClickHouse поддерживает также:
> - [Параметрические агрегатные функции](parametric_functions.md#aggregate_functions_parametric), которые помимо стоблцов принимаю и другие параметры.
> - [Комбинаторы](combinators.md#aggregate_functions_combinators), которые изменяют поведение агрегатных фунций.
- [Параметрические агрегатные функции](parametric_functions.md#aggregate_functions_parametric), которые помимо стоблцов принимаю и другие параметры.
- [Комбинаторы](combinators.md#aggregate_functions_combinators), которые изменяют поведение агрегатных фунций.
**Оглавление раздела**
```eval_rst
.. toctree::

View File

@ -1,18 +1,17 @@
<a name="aggregate_functions_reference"></a>
Справочник функций
==================
# Справочник функций
count()
-------
## count()
Считает количество строк. Принимает ноль аргументов, возвращает UInt64.
Не поддерживается синтаксис `COUNT(DISTINCT x)` - для этого есть отдельная агрегатная функция `uniq`.
Запрос вида `SELECT count() FROM table` не оптимизируется, так как количество записей в таблице нигде не хранится отдельно - из таблицы будет выбран какой-нибудь достаточно маленький столбец, и будет посчитано количество значений в нём.
any(x)
------
## any(x)
Выбирает первое попавшееся значение.
Порядок выполнения запроса может быть произвольным и даже каждый раз разным, поэтому результат данной функции недетерминирован.
@ -22,47 +21,73 @@ any(x)
При наличии в запросе `SELECT` секции `GROUP BY` или хотя бы одной агрегатной функции, ClickHouse (в отличие от, например, MySQL) требует, чтобы все выражения в секциях `SELECT`, `HAVING`, `ORDER BY` вычислялись из ключей или из агрегатных функций. То есть, каждый выбираемый из таблицы столбец, должен использоваться либо в ключах, либо внутри агрегатных функций. Чтобы получить поведение, как в MySQL, вы можете поместить остальные столбцы в агрегатную функцию `any`.
anyLast(x)
----------
## anyHeavy
Выбирает часто встречающееся значение с помощью алгоритма "[heavy hitters](http://www.cs.umd.edu/~samir/498/karp.pdf)". Если существует значение, которое встречается чаще, чем в половине случаев, в каждом потоке выполнения запроса, то возвращается данное значение. В общем случае, результат недетерминирован.
```
anyHeavy(column)
```
**Аргументы**
- `column` - Имя столбца.
**Пример**
Возьмем набор данных [OnTime](../getting_started/example_datasets/ontime.md#example_datasets-ontime) и выберем произвольное часто встречающееся значение в столбце `AirlineID`.
```sql
SELECT anyHeavy(AirlineID) AS res
FROM ontime
```
```
┌───res─┐
│ 19690 │
└───────┘
```
## anyLast(x)
Выбирает последнее попавшееся значение.
Результат так же недетерминирован, как и для функции `any`.
min(x)
------
## min(x)
Вычисляет минимум.
max(x)
------
## max(x)
Вычисляет максимум.
argMin(arg, val)
----------------
## argMin(arg, val)
Вычисляет значение arg при минимальном значении val. Если есть несколько разных значений arg для минимальных значений val, то выдаётся первое попавшееся из таких значений.
argMax(arg, val)
----------------
## argMax(arg, val)
Вычисляет значение arg при максимальном значении val. Если есть несколько разных значений arg для максимальных значений val, то выдаётся первое попавшееся из таких значений.
sum(x)
------
## sum(x)
Вычисляет сумму.
Работает только для чисел.
sumWithOverflow(x)
------------------
## sumWithOverflow(x)
Вычисляет сумму чисел, используя для результата тот же тип данных, что и для входных параметров. Если сумма выйдет за максимальное значение для заданного типа данных, то функция вернёт ошибку.
Работает только для чисел.
sumMap(key, value)
------------------
## sumMap(key, value)
Производит суммирование массива 'value' по соотвествующим ключам заданным в массиве 'key'.
Количество элементов в 'key' и 'value' должно быть одинаковым для каждой строки, для которой происходит суммирование.
@ -98,15 +123,14 @@ GROUP BY timeslot
└─────────────────────┴──────────────────────────────────────────────┘
```
avg(x)
------
## avg(x)
Вычисляет среднее.
Работает только для чисел.
Результат всегда - Float64.
uniq(x)
-------
## uniq(x)
Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей.
@ -115,8 +139,8 @@ uniq(x)
Результат детерминирован (не зависит от порядка выполнения запроса).
uniqCombined(x)
---------------
## uniqCombined(x)
Приближённо вычисляет количество различных значений аргумента. Работает для чисел, строк, дат, дат-с-временем, для нескольких аргументов и аргументов-кортежей.
@ -126,8 +150,8 @@ uniqCombined(x)
Функция `uniqCombined` является хорошим выбором по умолчанию для подсчёта количества различных значений.
uniqHLL12(x)
------------
## uniqHLL12(x)
Приближённо вычисляет количество различных значений аргумента, используя алгоритм [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog).
Используется 212 5-битовых ячеек. Размер состояния чуть больше 2.5 КБ.
@ -136,8 +160,8 @@ uniqHLL12(x)
В большинстве случаев, используйте функцию `uniq` или `uniqCombined`.
uniqExact(x)
------------
## uniqExact(x)
Вычисляет количество различных значений аргумента, точно.
Не стоит бояться приближённых расчётов. Поэтому, используйте лучше функцию `uniq`.
@ -145,8 +169,8 @@ uniqExact(x)
Функция `uniqExact` расходует больше оперативки, чем функция `uniq`, так как размер состояния неограниченно растёт по мере роста количества различных значений.
groupArray(x), groupArray(max_size)(x)
---------------------------------------
## groupArray(x), groupArray(max_size)(x)
Составляет массив из значений аргумента.
Значения в массив могут быть добавлены в любом (недетерминированном) порядке.
@ -158,8 +182,8 @@ groupArray(x), groupArray(max_size)(x)
<a name="agg_functions_groupArrayInsertAt"></a>
groupArrayInsertAt
------------------
## groupArrayInsertAt
Вставляет в массив значение в заданную позицию.
@ -170,13 +194,13 @@ groupArrayInsertAt
- Значение по умолчанию для подстановки на пустые позиции.
- Длина результирующего массива. Например, если вы хотите получать массисы одинакового размера для всех агрегатных ключей. При использовании этого параметра значение по умолчанию задавать обязательно.
groupUniqArray(x)
-----------------
## groupUniqArray(x)
Составляет массив из различных значений аргумента. Расход оперативки такой же, как у функции `uniqExact`.
quantile(level)(x)
------------------
## quantile(level)(x)
Приближённо вычисляет квантиль уровня level. level - константа, число с плавающей запятой от 0 до 1.
Рекомендуется использовать значения level в диапазоне 0.01..0.99.
@ -195,8 +219,8 @@ quantile(level)(x)
При использовании нескольких функций `quantile` (и аналогичных) с разными уровнями в запросе, внутренние состояния не объединяются (то есть, запрос работает менее эффективно, чем мог бы). В этом случае, используйте функцию `quantiles` (и аналогичные).
quantileDeterministic(level)(x, determinator)
---------------------------------------------
## quantileDeterministic(level)(x, determinator)
Работает аналогично функции `quantile`, но, в отличие от неё, результат является детерминированным и не зависит от порядка выполнения запроса.
@ -204,8 +228,8 @@ quantileDeterministic(level)(x, determinator)
Не используйте эту функцию для рассчёта таймингов. Для этого есть более подходящая функции - `quantileTiming`.
quantileTiming(level)(x)
------------------------
## quantileTiming(level)(x)
Вычисляет квантиль уровня level с фиксированной точностью.
Работает для чисел. Предназначена для расчёта квантилей от времени загрузки страницы в миллисекундах.
@ -227,26 +251,26 @@ quantileTiming(level)(x)
Для своей задачи (расчёт квантилей времени загрузки страниц), использование этой функции эффективнее и результат точнее, чем для функции `quantile`.
quantileTimingWeighted(level)(x, weight)
----------------------------------------
## quantileTimingWeighted(level)(x, weight)
Отличается от функции medianTiming наличием второго аргумента - «веса». Вес - неотрицательное целое число.
Результат считается так же, как если бы в функцию medianTiming\` значение x было передано weight количество раз.
quantileExact(level)(x)
-----------------------
## quantileExact(level)(x)
Вычисляет квантиль уровня level точно. Для этого, все переданные значения складываются в массив, который затем частично сортируется. Поэтому, функция потребляет O(n) памяти, где n - количество переданных значений. Впрочем, для случая маленького количества значений, функция весьма эффективна.
quantileExactWeighted(level)(x, weight)
---------------------------------------
## quantileExactWeighted(level)(x, weight)
Вычисляет квантиль уровня level точно. При этом, каждое значение учитывается с весом weight - как будто оно присутствует weight раз. Аргументы функции можно рассматривать как гистограммы, где значению x соответствует «столбик» гистограммы высоты weight, а саму функцию можно рассматривать как суммирование гистограмм.
В качестве алгоритма используется хэш-таблица. Из-за этого, в случае, если передаваемые значения часто повторяются, функция потребляет меньше оперативки, чем `quantileExact`. Вы можете использовать эту функцию вместо `quantileExact`, указав в качестве веса число 1.
quantileTDigest(level)(x)
-------------------------
## quantileTDigest(level)(x)
Вычисляет квантиль уровня level приближённо, с использованием алгоритма [t-digest](https://github.com/tdunning/t-digest/blob/master/docs/t-digest-paper/histo.pdf). Максимальная погрешность составляет 1%. Расход памяти на состояние пропорционален логарифму от количества переданных значений.
@ -254,55 +278,86 @@ quantileTDigest(level)(x)
Результат зависит от порядка выполнения запроса, и является недетерминированным.
median
------
## median
Для всех quantile-функций, также присутствуют соответствующие median-функции: `median`, `medianDeterministic`, `medianTiming`, `medianTimingWeighted`, `medianExact`, `medianExactWeighted`, `medianTDigest`. Они являются синонимами и их поведение ничем не отличается.
quantiles(level1, level2, ...)(x)
---------------------------------
## quantiles(level1, level2, ...)(x)
Для всех quantile-функций, также присутствуют соответствующие quantiles-функции: `quantiles`, `quantilesDeterministic`, `quantilesTiming`, `quantilesTimingWeighted`, `quantilesExact`, `quantilesExactWeighted`, `quantilesTDigest`. Эти функции за один проход вычисляют все квантили перечисленных уровней и возвращают массив вычисленных значений.
varSamp(x)
----------
Вычисляет величину `Σ((x - x̅)2) / (n - 1)`, где n - размер выборки, x̅ - среднее значение x.
## varSamp(x)
Вычисляет величину `Σ((x - x̅)^2) / (n - 1)`, где `n` - размер выборки, `x̅`- среднее значение `x`.
Она представляет собой несмещённую оценку дисперсии случайной величины, если переданные в функцию значения являются выборкой этой случайной величины.
Возвращает Float64. В случае, когда `n <= 1`, возвращается +∞.
Возвращает `Float64`. В случае, когда `n <= 1`, возвращается `+∞`.
varPop(x)
---------
## varPop(x)
Вычисляет величину `Σ((x - x̅)2) / n`, где n - размер выборки, x̅ - среднее значение x.
Вычисляет величину `Σ((x - x̅)^2) / n`, где `n` - размер выборки, `x̅`- среднее значение `x`.
То есть, дисперсию для множества значений. Возвращает Float64.
То есть, дисперсию для множества значений. Возвращает `Float64`.
stddevSamp(x)
-------------
## stddevSamp(x)
Результат равен квадратному корню от `varSamp(x)`.
stddevPop(x)
------------
## stddevPop(x)
Результат равен квадратному корню от `varPop(x)`.
covarSamp(x, y)
---------------
## topK
Возвращает массив наиболее часто встречающихся значений в указанном столбце. Результирующий массив упорядочен по убыванию частоты значения (не по самим значениям).
Реализует [Filtered Space-Saving](http://www.l2f.inesc-id.pt/~fmmb/wiki/uploads/Work/misnis.ref0a.pdf) алгоритм для анализа TopK, на основе reduce-and-combine
алгоритма из методики [Parallel Space Saving](https://arxiv.org/pdf/1401.0702.pdf).
```
topK(N)(column)
```
Функция не дает гарантированного результата, при определенных условиях возможны ошибки и вернутся частые, но не наиболее частые значения.
Рекомендуем использовать значения `N < 10`, при больших `N` снижается производительность. Максимально возможное значение `N = 65536`.
**Аргументы**
- 'N' - Количество значений.
- 'x' - Столбец.
**Пример**
Возьмем набор данных [OnTime](../getting_started/example_datasets/ontime.md#example_datasets-ontime) и выберем 3 наиболее часто встречающихся значения в столбце `AirlineID`.
```sql
SELECT topK(3)(AirlineID) AS res
FROM ontime
```
```
┌─res─────────────────┐
│ [19393,19790,19805] │
└─────────────────────┘
```
## covarSamp(x, y)
Вычисляет величину `Σ((x - x̅)(y - y̅)) / (n - 1)`.
Возвращает Float64. В случае, когда `n <= 1`, возвращается +∞.
covarPop(x, y)
--------------
## covarPop(x, y)
Вычисляет величину `Σ((x - x̅)(y - y̅)) / n`.
corr(x, y)
----------
Вычисляет коэффициент корреляции Пирсона: `Σ((x - x̅)(y - y̅)) / sqrt(Σ((x - x̅)2) * Σ((y - y̅)2))`.
## corr(x, y)
Вычисляет коэффициент корреляции Пирсона: `Σ((x - x̅)(y - y̅)) / sqrt(Σ((x - x̅)^2) * Σ((y - y̅)^2))`.

View File

@ -1,5 +1,6 @@
OnTime
======
<a name="example_datasets-ontime"></a>
# OnTime
Данный тест производительности был создан Вадимом Ткаченко, см: