我有以下连接3个表的要求
a) Table T1 - large physical table with 100 Million rows
Index columns: C1, C2, C3 in this order
b) Table T2 - Temp table with 50 records
contains C2 & additional columns. No Index
c) Table T3 - Temp table with 100 records
contains C3 & additional columns. No Index
表T2和T3没有公共列
我试图从T1、T2、T3中提取数据,如下所示:
Select T1.*, T2.*, T3.*
from T1
Inner join T2 (on T1.C2 = T2.C2)
Inner join T3 (T1.C3 = T3.C3)
where
T1.C1 = a constant value (coming from my program).
对上述查询的解释显示,在T1上,仅使用1列执行索引扫描。(我相信是T1.C3,因为我提供了WHERE子句)
查询执行得很好,但时间稍长。有没有更好的方法来为上述需求编码查询?
非常感谢任何输入
您提到您正在使用一个临时表。您是否在临时表上运行RUNSTATS,包括收集列统计信息?
一列上的索引扫描匹配必须与列1上的T1匹配相反,因为列1是索引的前导列。检查解释时,还应注意PRIMARY_ACCESSTYPE。Db2可以选择扫描T1、T2和T3中的一个或全部,并创建稀疏索引,该稀疏索引将用PLAN_TABLE中的PRIMARY_ACCESSTYPE=T来反映。
1亿行表上的3列索引的基数是多少?它是独一无二的吗?它是高度选择性的——接近1亿行的表大小,还是每个探测都有显著的重复行?
在这种情况下,准确的统计数据很重要。笛卡尔联接的成本相当高,因此Db2了解临时表的大小以及联接列在考虑要选择的访问路径时的选择性非常重要。如果没有在表T2和T3上收集统计信息,则Db2通过defuls假定表中有10000行。然后,T2和T3的笛卡尔连接将被估计为10000×10000行=1亿,那么Db2只使用局部滤波器访问该表一次,然后连接到T2和T3,可能使用稀疏索引,这将是有意义的。
如果无法解决收集统计信息的问题,请使用计划表结果更新问题。