PostgreSQL 的 TABLESAMPLE
子句实现支持自定义表采样方法,除了 SQL 标准要求的 BERNOULLI
和 SYSTEM
方法。当使用 TABLESAMPLE
子句时,采样方法确定表的哪些行将被选择。
在 SQL 级别,表采样方法由单个 SQL 函数来表示,通常以 C 语言实现,特征如下
method_name(internal) RETURNS tsm_handler
函数名称与出现在 TABLESAMPLE
子句中的方法名称相同。 internal
参数是一个虚拟内容(始终值为零),仅仅用于防止该函数直接从 SQL 命令被调用。函数的结果必须是一个 TsmRoutine
类型的 palloc'd 结构,其中包含对采样方法的支持函数的指针。这些支持函数是纯 C 函数,并且在 SQL 级别不可见或不可调用。支持函数在 58.1 节中进行说明。
除了函数指针之外, TsmRoutine
结构还必须提供这些附加字段
列表 *parameterTypes
当使用该采样方法时,这是一个包含参数数据类型 OID 的 OID 列表,这些参数由 TABLESAMPLE
子句接受。例如,对于内置方法,此列表包含一个项目,值为 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
子目录以了解附加方法。