2010-11-24 169 views
4

我被告知并随处阅读(但没有人敢于解释为什么),当在多列上组合索引时,出于性能原因,我应该首先放置最具选择性的列。 这是为什么? 这是一个神话吗?多列索引列顺序

+1

哇,很多问题的答案我不会让 – milan 2010-11-24 07:25:33

回答

6

我应该把最有选择性的列第一

According to Tom,列选择性对使用的所有列的索引的查询性能没有影响(它会影响甲骨文的压缩指数的能力)。

它不是第一件事,它不是最重要的东西。当然,这是值得考虑的事情,但它在事物的宏伟计划中相对较远。

在某些奇怪的,非常特殊和异常情况下(如上面真的完全偏斜数据),选择性易事然而,他们 真正依赖的价值观使用

一)非常罕见 B)在运行时,因为所有倾斜的查询都是

所以一般来说,看看你有的问题,尽量减少你需要的索引。

考虑 索引中的位置时,连接索引中列中不同值的数量不相关。

但是,在决定索引列顺序时,应考虑这些因素。更重要的是确保索引对许多查询有用,所以列顺序必须反映这些列的使用(或者缺少)以用于查询的where子句(出于AndreKR所阐述的原因)。

如何使用索引 - 这是决定时相关的内容。

所有其他的事情是平等的,我仍然会把最有选择性的列首先。它感觉不错...

更新:Another quote from Tom(感谢米兰找到它)。

在Oracle 5(是的,第5版!),还有为:首先将最有选择性的列 索引中的一个参数。

从那时起,在指数 中首先放置最具区分性的条目将会使指数变得更小或更有效。它似乎会,但它不会。

随着索引 密钥压缩,有一个引人注目的论据去相反的方式,因为它可以使指数 更小。但是,如前所述,这应该由您如何使用指数来驱动。

6

使用索引时,可以省略从右到左的列,即当您有索引col_a, col_b时,可以在WHERE col_a = x中使用它,但在WHERE col_b = x中不能使用它。

想象一下,有一本电话号码簿按姓氏排序,首字母为,然后是

至少在欧洲和美国,名字的选择性比姓氏低得多,因此查找名字不会缩小结果集,所以仍然会有很多页面来检查正确的姓氏。

+5

+1。如果领先的列丢失,您仍然可以使用索引,但它将是一个完整的索引扫描(或索引跳过扫描),这并不是那么有效(尽管如此,仍可能比全表扫描更好)。 – Thilo 2010-11-24 01:38:32

+0

虽然这并不回答关于选择性的部分。 – Thilo 2010-11-24 01:42:08

+0

我认为至少在欧洲和美国,名字的选择性比姓氏低得多,所以首先按名字排列的索引不会有太大的帮助。 – AndreKR 2010-11-24 01:43:44

2

索引中列的排序应该由您的查询决定,而不是任何选择性考虑因素。如果(a,b,c)有一个索引,并且大多数单列查询都是针对c列的,然后是a,然后将它们按c,a,b的顺序放在索引定义中以获得最佳效率。 Oracle倾向于在查询中使用索引的前沿,但可以在称为跳过扫描的效率较低的访问路径中使用索引中的其他列。

1

更具选择性的是您的指数,最快的是研究。

简单想象一个电话簿:你可以通过姓氏快速找到某人。但是,如果你有很多姓氏相同的人,那么你每次都要查看姓氏,这样你就会有更多的时间来寻找这个人。

因此,您必须先选择最具选择性的列,以尽可能避免此问题。

此外,您应该确保您的查询正确使用这些“选择性标准”。