SAMPLE 子句
SAMPLE
子句允许对 SELECT
查询进行近似处理。
当启用数据采样时,查询不会在所有数据上执行,而是在数据的特定部分(样本)上执行。例如,如果您需要计算所有访问的统计信息,执行查询即可,并在 1/10 的所有访问量上执行查询,然后将结果乘以 10。
近似查询处理在以下情况下可能很有用
- 当您有严格的延迟要求(例如低于 100 毫秒),但您无法证明额外的硬件资源成本以满足这些要求。
- 当您的原始数据不准确时,近似值不会显着降低质量。
- 业务需求以近似结果为目标(为了成本效益,或将精确结果推向高级用户)。
您只能将采样与 MergeTree 系列中的表一起使用,并且只有在表创建期间指定了采样表达式时(请参阅 MergeTree 引擎)。
数据采样的功能列在下面
- 数据采样是一种确定性机制。相同
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% 的样本。
[------++------]