2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5

第 59 章. 编写表采样方法

PostgreSQLTABLESAMPLE 子句的实现,除了支持 SQL 标准要求的 BERNOULLISYSTEM 方法外,还支持自定义的表采样方法。当使用 TABLESAMPLE 子句时,采样方法决定了哪些表行将被选中。

在 SQL 层面,表采样方法由一个单独的 SQL 函数表示,通常用 C 实现,其签名如下:

method_name(internal) RETURNS tsm_handler

该函数的名称与 TABLESAMPLE 子句中出现的的方法名称相同。internal 参数是一个占位符(值始终为零),它仅用于防止该函数直接从 SQL 命令中调用。函数的返回值必须是一个 palloc 分配的 TsmRoutine 类型结构体,该结构体包含指向采样方法支持函数的指针。这些支持函数是普通的 C 函数,在 SQL 层面不可见也无法调用。支持函数在第 59.1 节 中进行了描述。

除了函数指针,TsmRoutine 结构体还必须提供以下附加字段:

List *parameterTypes

这是一个 OID 列表,包含当使用此采样方法时 TABLESAMPLE 子句将接受的参数的数据类型 OID。例如,对于内置方法,此列表包含一个值为 FLOAT4OID 的项,代表采样百分比。自定义采样方法可以有更多或不同的参数。

bool repeatable_across_queries

如果为 true,则当提供相同的参数和 REPEATABLE 种子值,并且表内容未发生更改时,采样方法可以在连续查询中提供相同的样本。当此值为 false 时,REPEATABLE 子句不得与此采样方法一起使用。

bool repeatable_across_scans

如果为 true,则采样方法可以在同一查询中的连续扫描中提供相同的样本(假设参数、种子值和快照不变)。当此值为 false 时,规划器将不会选择需要扫描采样表多次的计划,因为这可能会导致查询输出不一致。

TsmRoutine 结构体类型声明在 src/include/access/tsmapi.h 中,更多详细信息请参见该文件。

标准发行版中包含的表采样方法是编写自己的方法的良好参考。请查看源树的 src/backend/access/tablesample 子目录以了解内置采样方法,并查看 contrib 子目录以了解附加方法。

提交更正

如果您在文档中发现任何不正确、与您对特定功能的使用经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。