我被告知并在任何地方阅读它(但没有人敢解释为什么),当在多列上编写索引时,出于性能原因,我应该将最具选择性的列放在第一位。 这是为什么? 这是一个神话吗?
答案 0 :(得分:6)
使用索引时,您可以从右到左省略列,即当您在col_a, col_b
上有索引时,可以在WHERE col_a = x
中使用它,但不能在WHERE col_b = x
中使用它
想象一下,电话簿按姓氏排序,然后按姓氏排序。
至少在欧洲和美国,名字的选择性比姓氏低很多,所以查找名字不会使结果集缩小太多,所以仍然会有很多页面要检查正确的姓氏。
答案 1 :(得分:6)
我应该把最具选择性的专栏放在第一位
According to Tom,列选择性对使用索引中所有列的查询没有性能影响(它确实会影响Oracle压缩索引的能力)。
这不是第一件事,它不是最重要的事情。当然,这是值得考虑的事情,但在宏观计划中相对较远。
在某些奇怪的,非常特殊和异常的情况下(如上面的数据真的完全偏斜),选择性很容易,但它们是
a)非常罕见 b)真正依赖于运行时使用的值,因为所有倾斜的查询都是
所以一般来说,看看你有的问题,尝试根据它来最小化你需要的索引。
在考虑时,连接索引中列中的不同值的数量无关 索引中的位置。
但是,在决定索引列顺序时,这些注意事项应该排在第二位。更重要的是确保索引对许多查询有用,因此列顺序必须反映查询的where子句中这些列的使用(或缺少这些列)(出于AndreKR所示的原因)。 / p>
您如何使用索引 - 这是决定时的相关内容。
在所有其他条件相同的情况下,我仍然会将最具选择性的列放在首位。感觉还不错......
更新: Another quote from Tom(感谢米兰找到它)。
在Oracle 5中(是的,版本5!),有一个参数可以将最具选择性的列放在第一位 在索引中。
从那时起,将最具辨别力的条目放在索引中是不正确的 将使索引更小或更有效。它似乎会,但它不会。
带索引 密钥压缩,有一个令人信服的论据,以另一种方式,因为它可以使索引 小。但是,它应该由您使用索引的方式驱动,如前所述。
答案 2 :(得分:2)
索引中列的排序应由您的查询确定,而不是任何选择性考虑因素。如果(a,b,c)上有索引,并且大多数单列查询都是针对列c,后跟a,则在索引定义中按c,a,b的顺序放置它们以获得最佳效率。 Oracle更倾向于使用索引的前沿进行查询,但可以在效率较低的访问路径中使用索引中的其他列,称为skip-scan。
答案 3 :(得分:1)
您的指数越具有选择性,研究速度最快。
简单地想象一下电话簿:你可以通过姓氏快速找到一个人。但如果你有很多人使用相同的姓氏,那么每次查看名字都会花费更多的时间来寻找这个人。
因此,您必须首先提供最具选择性的列,以尽可能避免此问题。
此外,您应该确保您的查询正确使用这些“选择性标准”。