类别:

查询语法

SAMPLE / TABLESAMPLE

返回从指定表中随机采样的行的子集。支持以下采样方法:

  • 对表的一小部分进行采样,并指定包含给定行的概率。返回的行数取决于表的大小和请求的概率。可以指定种子以使采样具有确定性。

  • 对固定的指定行数进行采样。除非表包含较少的行,否则将返回确切数量的指定行。

SAMPLE 与 TABLESAMPLE 同义,可以交换使用。

语法

SELECT ...
FROM ...
  { SAMPLE | TABLESAMPLE } [ samplingMethod ] ( { <probability> | <num> ROWS } ) [ { REPEATABLE | SEED } ( <seed> ) ]
[ ... ]
Copy

其中:

samplingMethod ::= { { BERNOULLI | ROW } |
                     { SYSTEM | BLOCK } }
Copy
BERNOULLI | ROW . SYSTEM | BLOCK

指定要使用的采样方法:

  • BERNOULLI`(或 :samp:`ROW):包含 probabilityp/100 的每行。类似于为每行掷一个加权的硬币。

  • SYSTEM`(或 :samp:`BLOCK):包含 probabilityp/100 的每个行块。类似于为每个行块掷一个加权的硬币。此方法不支持固定大小的采样。

采样方法是可选的。如果未指定方法,则默认为 BERNOULLI

probability . num ROWS

指定是根据表的一小部分还是根据表中的固定行数进行采样,其中:

  • probability 指定用于选择样本的百分比概率。可以是介于 0 (未选择行)和 100 (所有选择的行)之间的任何十进制数(包括这两个数字)。

  • num 指定要从表中采样的行数(最多 100 万行)。可以是介于 0 (未选择行)和 1000000 之间的任意整数(包括这两个数字)。

REPEATABLE | SEED ( seed )

指定种子值以使采样具有确定性。可以是介于 02147483647 之间的任意整数(包括这两个数字)。

使用说明

  • 以下关键字可以交换使用:

    • SAMPLE | TABLESAMPLE

    • BERNOULLI | ROW

    • SYSTEM | BLOCK

    • REPEATABLE | SEED

  • 返回的行数取决于指定的采样方法:

    基于小部分:
    • 对于 BERNOULLI | ROW 采样,预计返回的行数为 (p/100)*n

    • 对于 SYSTEM | BLOCK 采样,样本可能会有偏差,特别是对于小表。

    备注

    对于非常大的表,这两种方法之间的差异应该可以忽略不计。

    此外,由于采样是一个概率过程,因此返回的行数并不完全等于 (p/100)*n 行,但是会很接近。

    • 如果未指定 seed, SAMPLE 会在重复同一查询时生成不同的结果。

    • 如果表未发生变更,并且指定了相同的 seedprobability,SAMPLE 会生成相同的结果。但是,对表副本进行采样可能不会返回与对原始表进行采样相同的结果,即使指定了相同的 probabilityseed 也是如此。

    固定大小:
    • 如果表大于请求的行数,则始终返回请求的行数。

    • 如果表小于请求的行数,则返回整个表。

    • 固定大小的采样不支持 SYSTEM | BLOCKseed。例如,以下查询会产生错误:

      select * from example_table sample system (10 rows);
      
      select * from example_table sample row (10 rows) seed (99);
      
      Copy
  • 不支持对视图或子查询进行带 seed 的采样。例如,以下查询会产生错误:

    select * from (select * from example_table) sample (1) seed (99);
    
    Copy
  • 允许对 JOIN 的结果进行采样,但前提是满足以下 所有 条件:

    • 样本基于行 (Bernoulli)。

    • 采样不使用种子。

    采样是在完全处理联接后完成的。因此,采样不会减少联接的行数,也不会降低 JOIN 的成本。示例 部分包含了对 JOIN 的结果进行采样的示例。

  • 除了使用字面量来指定 probability | num ROWSseed 之外,还可以使用会话变量或绑定变量。

性能注意事项

  • SYSTEM | BLOCK 采样通常比 BERNOULLI | ROW 采样快。

  • 不带 seed 的采样通常比带 seed 的采样快。

  • 固定大小的采样可能比基于小部分的等效采样慢,因为固定大小的采样会阻止某些查询优化。

示例

基于小部分的行采样

返回表的样本,其中每行都有 10% 的概率包含在样本中:

SELECT * FROM testtable SAMPLE (10);
Copy

返回表的样本,其中每行都有 20.3% 的概率包含在样本中:

SELECT * FROM testtable TABLESAMPLE BERNOULLI (20.3);
Copy

返回整个表,包括表中的所有行:

SELECT * FROM testtable TABLESAMPLE (100);
Copy

返回一个空样本:

SELECT * FROM testtable SAMPLE ROW (0);
Copy

此示例演示如何对联接中的多个表进行采样:

SELECT i, j
    FROM
         table1 AS t1 SAMPLE (25)     -- 25% of rows in table1
             INNER JOIN
         table2 AS t2 SAMPLE (50)     -- 50% of rows in table2
    WHERE t2.j = t1.i
    ;
Copy

SAMPLE 子句仅适用于一个表,而不适用于 SAMPLE 子句之前的所有表或整个表达式。以下 JOIN 操作将 t1 的所有行联接到由 table2 中 50% 的行组成的样本;它不会对联接两个表中的所有行得到的 50% 的行进行采样:

SELECT i, j
    FROM table1 AS t1 INNER JOIN table2 AS t2 SAMPLE (50)
    WHERE t2.j = t1.i
    ;
Copy

要将 SAMPLE 子句应用于 JOIN 的结果而不是 JOIN 中的各个表,请将 JOIN 应用于包含 JOIN 的结果的内联视图。例如,将 JOIN 作为子查询执行,然后将 SAMPLE 应用于子查询的结果。下面的示例对 JOIN 返回的行的大约 1% 进行采样:

select *
   from (
         select *
            from t1 join t2
               on t1.a = t2.c
        ) sample (1);
Copy

基于小部分的块采样(带种子)

返回表的样本(其中每个行块都有 3% 的概率包含在样本中),并将种子设置为 82:

SELECT * FROM testtable SAMPLE SYSTEM (3) SEED (82);
Copy

返回表的样本(其中每个行块都有 0.012% 的概率包含在样本中),并将种子设置为 99992:

SELECT * FROM testtable SAMPLE BLOCK (0.012) REPEATABLE (99992);
Copy

备注

如果在不对表进行任何变更的情况下再次运行这两个查询中的任何一个,它们将返回相同的样本集。

固定大小的行采样

返回包含 10 行的固定大小的样本,每行都有 min(1, 10/n) 的概率包含在样本中,其中 n 是表中的行数:

SELECT * FROM testtable SAMPLE (10 ROWS);
Copy
语言: 中文