在MySQL Server 5.7源代码中,在查询计划程序中使用公式records = (x * (b-a) + a*c-b)/(c-1)
来计算密钥分发统计信息不可用时的记录数。
这个公式来自何处,它是如何得出的,或者为什么这个特定公式是正在使用的公式?它是否有一个既定的理论基础,如果有,它的基础是什么?
https://github.com/mysql/mysql-server/blob/5.7/sql/sql_planner.cc#L529
Assume that the first key part matches 1% of the file
and that the whole key matches 10 (duplicates) or 1
(unique) records.
Assume also that more key matches proportionally more
records
This gives the formula:
records = (x * (b-a) + a*c-b)/(c-1)
b = records matched by whole key
a = records matched by first key part (1% of all records?)
c = number of key parts in key
x = used key parts (1 <= x <= c)
答案 0 :(得分:0)
如果您完全没有关于问题的数据,则不得不进行估算。
该公式的一般形式在评论中解释:
x
列)的一个键列(c
),我们会得到a
行(占总行数的1%)。因此对于x=1
,根据定义,结果为a
。 b
);因此对于x=c
,我们根据定义获得b
行( 1 或 10 )。a-b
行不属于这种情况我们知道完整键(可能有b
行),根据定义,它们应按比例排除在可用键列的比例((x-1)/(c-1)
)之外。 -1
中的(x-1)/(c-1)
只是一个转变(您可以使用不同的变量名称),因为我们只需要计算其他列,但是{{1 }和c
是包含第一列的计数。 (在时间序列中,您可以调用第一列 x
的参数,t=0
完全相同。总而言之,我们得到-1
(a - (a-b) * (x-1)/(c-1)
代表第一个键列减去我们按比例排除的行数。这是(如果你稍微改变那个表达式)恰好给出的公式。快速完整性检查:对于a
(x=1
),第二项是 0 ,我们得到x-1=0
,由第一个条件定义;对于a
,我们得到第二个条件定义的x=c
。
使用这些假设来制作这个问题并不是没有道理的,但你可能会找到一个有意义的不同公式。认为它更好是一项艰巨的任务。
然后是选择值的问题(在这种情况下为a-(a-b)=b
和b=10
)。你显然可以选择任何价值。为了做到这一点,除了直觉之外没有任何可靠的数据,有一个名为Fermi estimate的概念:
估算技术以物理学家恩里科·费米(Enrico Fermi)的名字命名,因为他以很少或没有做出良好近似计算的能力而闻名。 实际数据。
您基本上只为输入参数选择了Magnite(1,1000000,1 / 100)的顺序,您的结果会得到合理的数量级。
那么你期望一个非唯一键覆盖多少行?它超过1,否则你会把它变成一个独特的键,但更像是2,10或100? 10可能是一个很好的猜测(它涵盖了该估计中大约3到30的值)。因此,虽然这个数字可能来自于一项关于密钥分配的2年全球调查,但10个权力的估计值通常是以这样的方式得出的。如果您想绝对确定,请询问开发人员。