PostgreSQL的TABLESAMPLE
子句实现支持
在 SQL 标准要求的BERNOULLI
和SYSTEM
方法之
外自定义表采样方法。采样方法决定了使用TABLESAMPLE
子句时
表的哪些行会被选择。
在 SQL 层上,一种表采样方法被表达为一个 SQL 函数(通常用 C 实现), 其签名是:
method_name(internal) RETURNS tsm_handler
函数的名称是出现在TABLESAMPLE
子句中的同一个方法名称。
internal
参数是不起作用的(总是值为零),它仅仅是为了阻止
直接从 SQL 命令中调用该函数。函数的结果必须是一个 palloc 好的
TsmRoutine
结构,它包含了该采样方法的支持函数的指针。
这些支持函数是纯 C 函数并且对于 SQL 层面不可见也不可调用。支持函数见
第 60.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
子目录中可以找到额外的方法。