“直方图给执行前的分布预测;分片运行时过滤给实际键集合的安全负证据;本页用完成后的真实规模作同义候选选择。三种信息的用法不同,但可以在一份查询记录中逐步对接。”
形式陈述
先规定摘要代表哪些行
一张表有很多重复值,优化器想在真正执行筛选前估计留下多少行。基数估计已经区分预测行数和真实行数;本页构造一种能逐项复算的单列摘要,让读者看清压缩在哪里丢失了信息。
输入是固定快照中的N个行出现,一列取NULL或已知整数域[L,U)内的值,L<U。给定严格递增的整数边界L=b₀<…<b_B=U。桶j包含整数b_j,…,b_{j+1}−1。本页完整扫描输入,不采用采样;摘要属于同一快照,不能在表已变更后继续宣称计数精确。
先统计每个非NULL值的出现数f(x)。按频数降序、同频时按值升序,保留至多m个值组成H,称为最常见值表MCV。这里的“常见”只决定保留顺序,没有要求每项必须超过某个概率门槛。其余非NULL行按值归桶,保存残余行数c_j;另保存NULL数n₀。必须满足
一份行出现只能进入这三部分中的一处。MCV值即使落在某个桶的数值范围内,它的行也已从c_j中移除。[1, §2.1–2.2;2, §69.1]
桶内采用什么预测
只知道一桶有8行,还不知道这些行集中在桶左边还是右边。本文明确采用一个有限整数位置模型:把该桶残余质量均匀分给不属于H的整数位置。记
若ℓ_j>0,每个剩余位置的预测频数为c_j/ℓ_j。ℓ_j=0时,该桶没有可放置残余行的位置,合法摘要必有c_j=0,贡献定义为零,不做0/0。没有出现过的整数也可能分到预测质量;这个模型没有保存真实支持集。
对整数阈值t,令s_j(t)是桶j内小于t、且不在H中的位置数。于是
s_j可先把t截到桶两端,算小于截断点的整数个数,再减去同一区间内的MCV值个数。等值查询x=h命中MCV时返回f(h);其余域内值用所在桶的c_j/ℓ_j,域外值为零。NULL不满足这里的普通等号或小于谓词,IS NULL则直接返回n₀。N>0时选择率为预测行数除以N;空表预测行数为零,接口不强算0/0。
这是本页的教学模型。PostgreSQL文档展示的是等频直方图中的插值及MCV质量组合,实际统计还来自采样;不能把本文固定整数桶、完整扫描的数值当作PostgreSQL执行计划复现。[2, §69.1]
直觉
精确质量与近似位置
MCV把很高的柱子单独保存,其高度不再被平均摊薄;残余桶只保存总高度,牺牲了柱子在桶内的位置。桶外完整部分可以相加,阈值穿过一桶时才需要桶内假设。
除去MCV的行却不除去它占据的位置,会把残余质量又分配给MCV键,使本文的两个子分布重叠。对整数域应按上面的ℓ_j计算。连续插值采用另一套位置模型,不能混用它的分母。
不相信均匀假设时,还能知道什么
对同一份新鲜、完整计数摘要,若s_j=0,该桶对x<t必贡献零;若s_j=ℓ_j,必贡献c_j。其余部分桶的真实贡献介于0和c_j之间。把MCV精确贡献与这些上下界相加,就得到确定性的行数区间。
对于一侧范围x<t,最多只有一个桶被阈值切开。因此区间宽度至多是该桶的残余行数,预测也必在此区间内。这不是统计置信区间,不含“95%”这样的概率;它直接来自所有符合摘要的行分布。MCV排名还能增加额外限制,本页给出的范围允许保守偏宽。
例子与边界
预测36/5,实际12
取N=24:NULL两行,8十行,0、1、4、5各一行,6和7各四行。域[0,12),桶[0,6)、[6,12),只保留一项MCV,因此H={8}、f(8)=10。两桶残余行数为4和8,剩余位置数为6和5。
查询x<8。第一桶全部进入,贡献4;第二桶只有6、7两个剩余位置在阈值内,MCV8本身不满足严格小于。预测为
选择率为(36/5)/24=3/10。真实执行保留四个低值行和八个6/7行,共12,真实选择率1/2。两者不同没有破坏质量恒等式,错误来自桶内均匀位置假设。
对x<6、x<12,阈值都在桶边界,摘要直接给4和22。对x=8,MCV给10;对并不存在的x=9,模型仍给8/5。预计非零不证明存在,预计很小也不允许执行器跳过真实谓词检查。
相同摘要,可以有不同答案
把四个6改成9,四个7改成10,其余行不变。MCV仍为8十行,桶计数仍为4和8,NULL仍为两行;新旧摘要完全相同。但x<8只保留0、1、4、5四行。
因此仅凭这份摘要无法区分真实数4与12。前述确定性区间[4,12]的两端都有合法数据见证;不能通过换一个舍入方式消除这八行的不确定性。若内存容量为8行槽,预测7.2或向上取整8都不能证明真实输入装得下。
摘要不是安全删除证据
增加新行、改变谓词列类型、改用NULL安全等号,都会改变合同。旧摘要仍可用于启发式成本预测,却不能继续拿原来的桶总数证明新快照的确定性上界。单列直方图也没有记录两列相关性,不能自动修正多个谓词相乘的误差;这部分仍回到旧基数估计页。
合法的残余桶可以为空,MCV可以覆盖全部非NULL值,整表也可以为空。边界必须严格递增、所有域内整数都有唯一桶;把重复边界留下再做插值,容易出现除零或同一行进两个桶。
推论与应用
构造、查询与真实成本
下载实现先用散列表统计D个不同非NULL键,再用比较排序按频数/键选MCV;用二分查找定位每个不同键的桶。设桶数B、实际保留项数h≤m,则在期望常数散列表访问与机器字算术模型下,构造成本为
构造期保留计数表,空间O(D+B+1);交付摘要只需O(h+B+1)。它没有保存域[L,U)的每一个位置,所以巨大数值跨度不直接产生巨大数组。
本文范围查询扫描桶与MCV,成本O(B+h+1),同时得到预测和计数上下界。等值查询散列表先查MCV,未命中才二分定位,成本为期望O(1+log(B+1))。Fraction的约分、大整数位长和排序键比较成本另计,不因字段数固定就变成固定纳秒。
预测交给选择,事实交给执行
直方图帮助优化器比较候选,但实际完成一个物化子计划后,应将已观察到的真实行数交给检查点重优化。执行中的完整运行时过滤则提供另一类信息:它的负结果可在相应合同下证明某个键不可能匹配,所依赖的证据不是均匀分布。
共同终点把36/5预测、12行物化事实、6个过滤候选和两种后缀计划放在同一份记录中;核验器保留原始出现身份,便于换分布后重算。
参考资料
- Viswanath Poosala、Yannis E. Ioannidis、Peter J. Haas、Eugene J. Shekita,“Improved Histograms for Selectivity Estimation of Range Predicates”,SIGMOD1996,§2.1–2.2、Figure1,印刷p.295:域、频数、分桶及桶内假设。本文扣除MCV位置的有限整数模型与24行数据另行规定。
- PostgreSQL18,Row Estimation Examples,§69.1,等频桶插值、MCV等值与范围质量组合;pg_stats的histogram_bounds及most_common_freqs说明。