0

我有加入 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 子句)

查询执行良好,但花费的时间稍长。有没有更好的方法来对上述要求的查询进行编码?

非常感谢任何输入

4

1 回答 1

0

您提到您正在使用临时表。您是否在临时表上运行了 RUNSTATS,包括收集列统计信息?

一列上的索引扫描匹配必须针对列 1 上的 T1 匹配,因为那是索引的前导列。检查说明时,还应注意PRIMARY_ACCESSTYPE。Db2 可以选择扫描 T1、T2 和 T3 中的一个或全部并创建稀疏索引,这将在 PLAN_TABLE 中通过 PRIMARY_ACCESSTYPE = T 反映出来。

1亿行表的3列索引的基数是多少?它是独一无二的吗?它是高度选择性的 - 接近 1 亿行的表大小,还是大量重复行符合每个探测的条件?

在这种情况下,准确的统计数据很重要。笛卡尔连接的成本相当高,因此 Db2 了解临时表的大小以及连接列在考虑选择的访问路径时的选择性非常重要。如果没有在表 T2 和 T3 上收集统计信息,则默认情况下 Db2 假定表中有 10,000 行。然后 T2 和 T3 的笛卡尔连接估计为 10,000 * 10,000 行 = 1 亿,那么 Db2 使用本地过滤器访问该表一次是有意义的,然后连接到 T2 和 T3,可能使用稀疏索引.

如果收集统计信息无法解决,请使用计划表结果更新问题。

于 2019-10-23T17:10:58.203 回答