PostgreSQL日期范围查询中Explain行数估算机制相关问题
PostgreSQL daterange类型查询行数估算逻辑解答
问题1:stakind2=6与Stavalue2的含义
PostgreSQL内部对范围类型字段预设了专属统计类型编码,其中stakind=6对应的是范围长度直方图统计,内部编号为STATISTIC_KIND_RANGE_LENGTH_HISTOGRAM。
你示例中的Stavalue2和Stavalue1的样本是一一对应的,存储的是对应样本范围的长度分布频率值,用于修正不同长度范围的重叠概率计算偏差。你给出的{1,1,1}是简化示意,实际生产环境中会是归一化后的频率占比,反映不同长度的范围值在全表中的出现比例。
问题2:日期区间类型直方图的解读方法
你看到的存储在Stavalue1里的区间列表,对应stakind=7的范围值样本直方图,内部编号为STATISTIC_KIND_RANGE_HISTOGRAM,是对表中daterange字段值等频采样得到的有序样本集,按范围下界升序排序。
解读规则如下:
- 列表中每一个元素都是从表中实际采样得到的period字段值
- 样本覆盖了字段值的整体分布区间,样本数量和表的统计目标参数
default_statistics_target相关 - 每个样本对应统计直方图的一个桶,用于后续重叠率的计算
比如你给出的三个样本,就代表采样得到的三个典型日期范围,分别覆盖1月初、1月末到2月初、2月中旬的时间段。
问题3:示例查询的行数估算流程
你给出的交集查询SELECT * FROM Table1 WHERE period && '[2015-01-01,2015-12-30)';,Explain的行数估算会按以下步骤执行:
- 先从
pg_class系统表读取Table1的总元组估值reltuples,记为总条数N - 提取
period字段对应的两类统计值:stakind=7的范围样本列表、stakind=6的长度分布统计 - 遍历所有采样的范围样本,计算每个样本和查询范围
[2015-01-01,2015-12-30)的重叠比例:- 样本完全落在查询范围内,重叠比例为1
- 样本和查询范围完全无交集,重叠比例为0
- 样本和查询范围部分重叠,重叠比例为
重叠长度 / 样本自身总长度
- 所有样本的重叠比例求和后除以样本总数,得到平均重叠率
P - 用长度直方图的统计结果修正
P的偏差,避免因为样本长度分布不均导致的估算误差 - 最终估算返回行数 = 总条数
N* 修正后的重叠率P
内容的提问来源于stack exchange,提问作者liana
相关产品推荐
相关产品推荐

