我被告知并在各处阅读它(但没有人敢解释原因),在多列上编写索引时,出于性能原因,我应该将最具选择性的列放在首位。这是为什么?这是一个神话吗?
4 回答
使用索引时,您可以从右到左省略列,即当您有索引时,col_a, col_b
您可以使用它,WHERE col_a = x
但您不能使用它WHERE col_b = x
。
想象有一个电话簿,它先按名字排序,然后按姓氏排序。
至少在欧洲和美国,名字的选择性比姓氏要低得多,因此查找名字不会缩小结果集的范围,因此仍然会有很多页面来检查正确的姓氏。
我应该把最有选择性的列放在第一位
根据 Tom的说法,列选择性对于使用索引中所有列的查询没有性能影响(它确实会影响 Oracle 压缩索引的能力)。
这不是第一件事,也不是最重要的事情。当然,这是需要考虑的事情,但在宏伟的计划中相对较远。
在某些奇怪的、非常特殊的和异常的情况下(比如上面的数据完全倾斜),选择性很容易很重要,但是,它们是
a) 非常罕见 b) 真正依赖于运行时使用的值,因为所有倾斜查询都是
所以总的来说,看看你有什么问题,试着在此基础上最小化你需要的索引。
在考虑索引中的位置时,连接索引中的列中不同值的数量无关紧要。
但是,在决定索引列顺序时,这些考虑应该排在第二位。更重要的是要确保索引对许多查询有用,因此列顺序必须反映查询的 where 子句中这些列的使用(或缺少这些列)(出于 AndreKR 说明的原因)。
你如何使用索引——这是决定时的相关内容。
在所有其他条件相同的情况下,我仍然会将最具选择性的列放在首位。就是觉得对...
更新: 汤姆的另一句话(感谢米兰找到它)。
在 Oracle 5(是的,版本 5!)中,有一个论点是将最具选择性的列放在索引中的首位。
从那时起,将最有区别的条目放在索引中的第一个会使得索引更小或更高效是不正确的。似乎会,但不会。
使用索引键压缩,有一个令人信服的论点可以采用另一种方式,因为它可以使索引更小。但是,它应该由您如何使用索引来驱动,如前所述。
索引中列的顺序应由您的查询决定,而不是任何选择性考虑因素。如果你在 (a,b,c) 上有一个索引,并且你的单列查询大部分都是针对 c 列,然后是 a,那么在索引定义中按照 c,a,b 的顺序排列,以获得最佳效率. Oracle 更喜欢使用索引的前沿进行查询,但可以在效率较低的访问路径(称为跳过扫描)中使用索引中的其他列。
您的索引越有选择性,研究就越快。
简单地想象一个电话簿:你可以通过姓氏快速找到某人。但是,如果您有很多人的姓氏相同,那么您每次都会通过查看名字来持续更多的时间来寻找这个人。
所以你必须首先给出最具选择性的列,以尽可能避免这个问题。
此外,您应该确保您的查询正确使用这些“选择性标准”。