跳至主要内容

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这里 km 是 0 到 1 之间的数字。查询在 k 部分数据样本上执行。用于样本的数据偏移了 m 部分。 了解更多

SAMPLE K

这里 k 是 0 到 1 之间的数字(支持分数和小数表示法)。例如,SAMPLE 1/2SAMPLE 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

这里 km 是 0 到 1 之间的数字。示例如下所示。

示例 1

SAMPLE 1/10

在此示例中,样本是所有数据的 1/10。

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

示例 2

SAMPLE 1/10 OFFSET 1/2

这里,从数据的后半部分取 10% 的样本。

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