第 58 章 编写一种表采样方法
PostgreSQL 对 TABLESAMPLE 子句的实现,除了支持 SQL 标准要求的 BERNOULLI 和
SYSTEM 方法之外,还支持自定义表采样方法。采样方法决定了在使用 TABLESAMPLE 子句时会选取表中的哪些行。
在 SQL 层面,表采样方法由一个 SQL 函数表示,通常用 C 实现,其签名如下:
method_name(internal) RETURNS tsm_handler
函数名与出现在 TABLESAMPLE 子句中的方法名相同。internal 参数只是一个占位值(其值始终为零),用来防止该函数被
SQL 命令直接调用。该函数的结果必须是一个通过 palloc 分配的
TsmRoutine 结构体,其中包含该采样方法支持函数的指针。这些支持函数是普通的 C 函数,在 SQL 层面既不可见也不可调用。支持函数见第 58.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 子目录中。
报告文档问题
阅读 上游文档. 通过 PostgreSQL 文档反馈表单.