带参数标记的不等于
谓语条件 c1 >= ? 或者 c1 <= ?,filter factor 为:
=
{
0.1
if
c
o
l
c
a
r
d
≤
25
1
5
×
c
o
l
c
a
r
d
79
if
c
o
l
c
a
r
d
>
25
=\left\{ \begin{array}{l} 0.1 & \text{ if }colcard\le25\\ \frac{1}{5\times\sqrt\frac{colcard}{79}} & \text{ if }colcard>25 \end{array} \right.
={0.15×79colcard1 if colcard≤25 if colcard>25
谓语条件 c1 <= ? and c1 >= ? 或者 c1 between ? and ?,filter factor 为:
=
{
0.33
if
c
o
l
c
a
r
d
≤
25
6
100
×
c
o
l
c
a
r
d
79
if
c
o
l
c
a
r
d
>
25
=\left\{ \begin{array}{l} 0.33 & \text{ if }colcard\le25\\ \frac{6}{100\times\sqrt\frac{colcard}{79}} & \text{ if }colcard>25 \end{array} \right.
={0.33100×79colcard6 if colcard≤25 if colcard>25
推理方法
创建一张测试表,并插入若干数据:
create table testn (c1 decimal(24,6))
insert into testn values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
收集统计信息,并对 c1 字段的 colcard 做“伪造”:
runstats on table testn
UPDATE SYSSTAT.TABLES SET CARD=79 WHERE TABNAME = 'TESTN' AND TABSCHEMA = 'DB2INST1'
UPDATE SYSSTAT.COLUMNS SET COLCARD=79 WHERE COLNAME = 'C1' AND TABNAME = 'TESTN' AND TABSCHEMA = 'DB2INST1'
生成执行计划并打印:
db2 "explain all for select * from testn where c1 < ?"
db2exfmt -d sample -1
观察 c1 < ? 的 filter factor:
2) Sargable Predicate,
Comparison Operator: Less Than (<)
Subquery Input Required: No
Filter Factor: 0.2
Predicate Text:
--------------
(Q1.C1 < ?)
可以看到是 0.2,以此类推,迭代不同的 colcard 进行“伪造”,就能得到 colcard 和 filter factor 之间的关系,根据每逢 colcard 是 79 的完全平方数倍数就能得到是有理数的 filter factor,从而推出上述公式。
组合列
两列的交集
可以转换成同一维度
例如 c1 <= v2 and c1 >= v1,可以转换成 c1 between v1 and v2,filter factor 为:
F
F
(
c
1
≤
v
2
)
+
F
F
(
c
1
≥
v
1
)
−
F
F
(
c
1
≤
v
2
)
∪
F
F
(
c
1
≥
v
1
)
\ FF(c1\le v2)+FF(c1\ge v1)-FF(c1\le v2)\cup FF(c1\ge v1)
FF(c1≤v2)+FF(c1≥v1)−FF(c1≤v2)∪FF(c1≥v1)
不能转换成同一维度
例如 c1 = v1 and c2 = v2,无法转换成同一纬度,则 filter factor 为:
max
(
min
(
1
c
o
l
g
r
o
u
p
c
a
r
d
,
F
F
(
c
1
=
v
1
)
,
F
F
(
c
2
=
v
2
)
)
,
F
F
(
c
1
=
v
1
)
×
F
F
(
c
2
=
v
2
)
)
\ \max(\min(\frac{1}{colgroupcard},FF(c1=v1),FF(c2=v2)),FF(c1=v1)\times FF(c2=v2))
max(min(colgroupcard1,FF(c1=v1),FF(c2=v2)),FF(c1=v1)×FF(c2=v2))
两列的并集
可以转换成同一维度
例如 c1 <= v2 or c1 >= v1,filter factor 为:
min
(
1
,
F
F
(
c
1
≤
v
2
)
+
F
F
(
c
1
≥
v
1
)
)
\ \min(1,FF(c1\le v2)+FF(c1\ge v1))
min(1,FF(c1≤v2)+FF(c1≥v1))
不能转换成同一维度
例如 c1 = v1 or c2 = v2,无法转换成同一纬度,则 filter factor 为:
F
F
(
c
1
=
v
1
)
+
F
F
(
c
2
=
v
2
)
−
F
F
(
c
1
=
v
1
)
∩
F
F
(
c
2
=
v
2
)
\ FF(c1=v1)+FF(c2=v2)-FF(c1=v1)\cap FF(c2=v2)
FF(c1=v1)+FF(c2=v2)−FF(c1=v1)∩FF(c2=v2)
组合列的例子
考虑如下 SQL:
select
roleid,
sortid,
action,
approve,id
from
klbsuser.km_role_popedom_sort
where
roleid='52fd731c7c533217399567' and action='SeekAdd' and approve='T'
action 正好出现在 Frequency 中,所以 FF(action) = 0.1115
roleid 不在 Frequency 中,减去后平均得到 FF(roleid) = 0.0227293
approve 我们通过 selectivity 加以控制,FF(approve) 取值从0.001到1不等
column group cards=714,所以 FF(CGC) = 0.0014
FF(action) | FF(roleid) | FF(approve) | FF(CGC) | FF1*FF2*FF3 | WINNER |
---|---|---|---|---|---|
0.1115 | 0.0227293 | 1 | 0.0014 | 0.0025343 | FF1*FF2*FF3 |
0.1115 | 0.0227293 | 0.1 | 0.0014 | 0.0025343 | FF(CGC) |
0.1115 | 0.0227293 | 0.0015 | 0.0014 | 0.0000038 | FF(CGC) |
0.1115 | 0.0227293 | 0.001 | 0.0014 | 0.0000025 | FF(approve) |