假设我有一个带有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
答案 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如果我错在任何部分,请纠正我