SAMPLE 子句
SAMPLE
子句允许近似的 SELECT
查询处理。
当启用数据抽样时,查询不是在所有数据上执行,而仅在数据的某个部分(样本)上执行。例如,如果您需要计算所有访问的统计信息,则只需在所有访问的 1/10 部分上执行查询,然后将结果乘以 10 即可。
在以下情况下,近似查询处理可能很有用
- 当您有严格的延迟要求(例如低于 100 毫秒),但您无法证明增加额外硬件资源以满足这些要求的成本是合理的。
- 当您的原始数据不准确时,近似不会显着降低质量。
- 业务需求目标是近似结果(为了成本效益,或将精确结果推销给高级用户)。
数据抽样的特性如下
- 数据抽样是一种确定性机制。 同一个
SELECT .. SAMPLE
查询的结果始终相同。 - 抽样对于不同的表一致地工作。 对于具有单个抽样键的表,具有相同系数的样本始终选择可能的相同数据子集。 例如,用户 ID 样本从不同表中提取具有相同可能用户 ID 子集的行。 这意味着您可以在 IN 子句中的子查询中使用样本。 此外,您可以使用 JOIN 子句连接样本。
- 抽样允许从磁盘读取更少的数据。 请注意,您必须正确指定抽样键。 有关更多信息,请参阅创建 MergeTree 表。
对于 SAMPLE
子句,支持以下语法
SAMPLE 子句 语法 | 描述 |
---|---|
SAMPLE k | 此处 k 是 0 到 1 之间的数字。查询在 k 部分数据上执行。 例如,SAMPLE 0.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
。
在这种情况下,查询在至少 n
行(但不显着多于此)的样本上执行。 例如,SAMPLE 10000000
在至少 10,000,000 行上运行查询。
由于数据读取的最小单位是一个粒度(其大小由 index_granularity
设置确定),因此设置一个远大于粒度大小的样本是有意义的。
当使用 SAMPLE n
子句时,您不知道处理了数据的相对百分比。 因此您不知道聚合函数应乘以的系数。 使用 _sample_factor
虚拟列来获得近似结果。
_sample_factor
列包含动态计算的相对系数。 当您创建具有指定抽样键的表时,将自动创建此列。 _sample_factor
列的用法示例如下所示。
让我们考虑表 visits
,其中包含有关网站访问的统计信息。 第一个示例显示如何计算页面浏览量
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 之间的数字。 示例如下所示。
示例 1
SAMPLE 1/10
在此示例中,样本是所有数据的 1/10
[++------------]
示例 2
SAMPLE 1/10 OFFSET 1/2
在这里,从数据的后半部分中抽取了 10% 的样本。
[------++------]