ClickHouse/docs/ru/sql-reference/statements/select/sample.md
2022-04-09 07:29:05 -06:00

11 KiB
Raw Blame History

sidebar_label
SAMPLE

Секция SAMPLE

Секция SAMPLE позволяет выполнять запросы приближённо. Например, чтобы посчитать статистику по всем визитам, можно обработать 1/10 всех визитов и результат домножить на 10.

Сэмплирование имеет смысл, когда:

  1. Точность результата не важна, например, для оценочных расчетов.

  2. Возможности аппаратной части не позволяют соответствовать строгим критериям. Например, время ответа должно быть <100 мс. При этом точность расчета имеет более низкий приоритет.

  3. Точность результата участвует в бизнес-модели сервиса. Например, пользователи с бесплатной подпиской на сервис могут получать отчеты с меньшей точностью, чем пользователи с премиум подпиской.

    :::note "Внимание" Не стоит использовать сэмплирование в тех задачах, где важна точность расчетов. Например, при работе с финансовыми отчетами. ::: Свойства сэмплирования:

  • Сэмплирование работает детерминированно. При многократном выполнении одного и того же запроса SELECT .. SAMPLE, результат всегда будет одинаковым.
  • Сэмплирование поддерживает консистентность для разных таблиц. Имеется в виду, что для таблиц с одним и тем же ключом сэмплирования, подмножество данных в выборках будет одинаковым (выборки при этом должны быть сформированы для одинаковой доли данных). Например, выборка по идентификаторам посетителей выберет из разных таблиц строки с одинаковым подмножеством всех возможных идентификаторов. Это свойство позволяет использовать выборки в подзапросах в секции IN, а также объединять выборки с помощью JOIN.
  • Сэмплирование позволяет читать меньше данных с диска. Обратите внимание, для этого необходимо корректно указать ключ сэмплирования. Подробнее см. в разделе Создание таблицы MergeTree.

Сэмплирование поддерживается только таблицами семейства MergeTree и только в том случае, если для таблиц был указан ключ сэмплирования (выражение, на основе которого должна производиться выборка). Подробнее см. в разделе Создание таблиц MergeTree.

Выражение SAMPLE в запросе можно задать следующими способами:

Способ задания SAMPLE Описание
SAMPLE k Здесь k это дробное число в интервале от 0 до 1.
Запрос будет выполнен по k доле данных. Например, если указано SAMPLE 1/10, то запрос будет выполнен для выборки из 1/10 данных. Подробнее
SAMPLE n Здесь n это достаточно большое целое число.
Запрос будет выполнен для выборки, состоящей из не менее чем n строк. Например, если указано SAMPLE 10000000, то запрос будет выполнен для не менее чем 10,000,000 строк. Подробнее
SAMPLE k OFFSET m Здесь k и m числа от 0 до 1.
Запрос будет выполнен по k доле данных. При этом выборка будет сформирована со смещением на m долю. Подробнее

SAMPLE k

Здесь k число в интервале от 0 до 1. Поддерживается как дробная, так и десятичная форма записи. Например, SAMPLE 1/2 или SAMPLE 0.5.

Если задано выражение SAMPLE k, запрос будет выполнен для k доли данных. Рассмотрим пример:

SELECT
    Title,
    count() * 10 AS PageViews
FROM hits_distributed
SAMPLE 0.1
WHERE
    CounterID = 34
GROUP BY Title
ORDER BY PageViews DESC LIMIT 1000

В этом примере запрос выполняется по выборке из 0.1 (10%) данных. Значения агрегатных функций не корректируются автоматически, поэтому чтобы получить приближённый результат, значение count() нужно вручную умножить на 10.

Выборка с указанием относительного коэффициента является «согласованной»: для таблиц с одним и тем же ключом сэмплирования, выборка с одинаковой относительной долей всегда будет составлять одно и то же подмножество данных. То есть выборка из разных таблиц, на разных серверах, в разное время, формируется одинаковым образом.

SAMPLE n

Здесь n это достаточно большое целое число. Например, SAMPLE 10000000.

Если задано выражение SAMPLE n, запрос будет выполнен для выборки из не менее n строк (но не значительно больше этого значения). Например, если задать SAMPLE 10000000, в выборку попадут не менее 10,000,000 строк.

:::note "Примечание"
Следует иметь в виду, что `n` должно быть достаточно большим числом. Так как минимальной единицей данных для чтения является одна гранула (её размер задаётся настройкой `index_granularity` для таблицы), имеет смысл создавать выборки, размер которых существенно превосходит размер гранулы.
:::

При выполнении SAMPLE n коэффициент сэмплирования заранее неизвестен (то есть нет информации о том, относительно какого количества данных будет сформирована выборка). Чтобы узнать коэффициент сэмплирования, используйте столбец _sample_factor.

Виртуальный столбец _sample_factor автоматически создается в тех таблицах, для которых задано выражение SAMPLE BY (подробнее см. в разделе Создание таблицы MergeTree). В столбце содержится коэффициент сэмплирования для таблицы он рассчитывается динамически по мере добавления данных в таблицу. Ниже приведены примеры использования столбца _sample_factor.

Предположим, у нас есть таблица, в которой ведется статистика посещений сайта. Пример ниже показывает, как рассчитать суммарное число просмотров:

SELECT sum(PageViews * _sample_factor)
FROM visits
SAMPLE 10000000

Следующий пример показывает, как посчитать общее число визитов:

SELECT sum(_sample_factor)
FROM visits
SAMPLE 10000000

В примере ниже рассчитывается среднее время на сайте. Обратите внимание, при расчете средних значений, умножать результат на коэффициент сэмплирования не нужно.

SELECT avg(Duration)
FROM visits
SAMPLE 10000000

SAMPLE k OFFSET m

Здесь k и m числа в интервале от 0 до 1. Например, SAMPLE 0.1 OFFSET 0.5. Поддерживается как дробная, так и десятичная форма записи.

При задании SAMPLE k OFFSET m, выборка будет сформирована из k доли данных со смещением на долю m. Примеры приведены ниже.

Пример 1

SAMPLE 1/10

В этом примере выборка будет сформирована по 1/10 доле всех данных:

[++------------------]

Пример 2

SAMPLE 1/10 OFFSET 1/2

Здесь выборка, которая состоит из 1/10 доли данных, взята из второй половины данных.

[----------++--------]