相同列组合上的DB2 Multiple Index

时间:2009-10-28 04:11:09

标签: db2 indexing

假设我有一个带有C1,C2 ...... C10列的表T.

C1,C2和C3是多个查询中最常被引用的列。无法控制这些列的引用顺序。

为了提高查询性能,我需要创建多个索引,如(C1,C2,C3),(C1,C3,C2),(C2,C1,C3),(C2,C3,C1)等?

以两个类似的查询为例......

选择*   从t1,t2  其中t1.c1 = t2.c1    并且t1.c2 = t2.c2    和t1.c3 = t3.c3    和

选择*   从t1,t2  其中t1.c2 = t2.c2    并且t1.c1 = t2.c1    和t1.c3 = t3.c3

我是否需要两个索引(C1,C2,C3)和(C2,C1,C3)来提高上述两个不同查询的性能,或者只是任何一个组合对于这两个查询都足够了?

我想这不是必需的,并且假设DB2足够聪明,只要使用C1,C2和C3,就可以重新排列查询中的列以匹配任何一个索引组合。

任何人都可以确认并指出一些与此相关的文章。

AIX中使用的DB2版本为9.5

3 个答案:

答案 0 :(得分:1)

数据库调优不仅仅是一种一劳永逸的操作,不仅仅是投资Bernie Madhoff的对冲基金: - )

Yous应提供适度智能的第一次猜测(基于预期行为),然后监视,在生产中,执行的查询。

您应该至少从各列的索引开始。然后,如果有人抱怨他们的查询花费的时间太长,请让DB2分析查询并查看瓶颈在哪里(解释计划或Visual Explain)。此时,您应该确定添加索引的成本是否超过了收益。

这是唯一的方式,可以确保您的数据库正确调整。

您认为DB2可以重新排序以使用其他索引的东西完全取决于查询 - 除了最简单的查询之外,所有这些都将使您的假设失效。

例如,假设你有索引(c1,c2)。查询

select * from t where c2 = '2009-01-01';

使用该索引,因为所有c2个关键部分都散布在索引周围,而不是在一个区域内。

可以足够优化

select * from t where c2 = '2009-01-01' and c1 = 'x';

因为它可以在索引中查找x2009-01-01。然而,

select * from t where c2 <= '2009-01-01' and c2 <= '2009-01-05' and c1 = 'x';

遇到与第一个查询相同的问题 - c2关键部分在索引中不连续。

这就是为什么你应该衡量,而不是猜测

答案 1 :(得分:1)

在DB2 for Linux / UNIX / Windows中,从优化器的角度来看,查询中谓词和连接条件的顺序无关紧要。优化程序的查询重写部分将考虑到这一点。

根据查询,优化程序可以选择索引,无论是(C3,C2,C1)还是(C1,C2,C3)。但是,这并不是说索引中的列顺序无关紧要 - 确实如此。通常,您希望将列以最高基数的顺序排列到最低基数,但当然有很多例外。有关于正确索引设计的全书(Lahdenmaki / Leach的书非常好),所以我建议您研究这些。

答案 2 :(得分:1)

我对DB2不是很确定,但在oracle wat中发生的是当我们创建索引时说

在T1上创建INDEX I1(c1);

然后它将在列(c1)上创建一个索引并对其进行排序。

在您的情况下包含复合索引:

在T2上创建INDEX I2(c1,c2)

它将以排序格式存储数据。所以请记住这一点,我想在上面的索引中查询第一列会更快,如下所示:

从T2

中选择c1,c2

如果我错在任何部分,请纠正我