多列索引列顺序
Posted
技术标签:
【中文标题】多列索引列顺序【英文标题】:multicolumn index column order 【发布时间】:2011-05-14 20:15:52 【问题描述】:我被告知并在各处阅读它(但没有人敢解释原因),在多列上编写索引时,出于性能原因,我应该将最具选择性的列放在首位。 这是为什么? 是神话吗?
【问题讨论】:
哇,这么多问题我没有回答 【参考方案1】:我应该把最有选择性的列放在第一位
According to Tom,列选择性对于使用索引中所有列的查询没有性能影响(它确实会影响 Oracle 压缩索引的能力)。
这不是第一件事,也不是最重要的事情。当然,这是值得考虑的事情,但在宏伟的计划中相对较远。
在某些奇怪的、非常奇特的和异常的情况下(比如上面的数据完全歪斜),选择性很容易很重要,但是,它们是
a) 非常罕见 b) 真正依赖于运行时使用的值,因为所有倾斜查询都是
所以一般来说,看看你有什么问题,试着在此基础上尽量减少你需要的索引。
在考虑时,连接索引中的列中不同值的数量不相关 索引中的位置。
但是,在决定索引列的顺序时,这些考虑应该排在第二位。更重要的是要确保索引对许多查询有用,因此列顺序必须反映查询的 where 子句中这些列的使用(或缺少这些列)(出于 AndreKR 说明的原因)。
你如何使用索引——这是决定时的相关因素。
在所有其他条件相同的情况下,我仍然会将最具选择性的列放在首位。感觉刚刚好……
更新: Another quote from Tom(感谢 milan 找到它)。
在 Oracle 5(是的,版本 5!)中,有一个论点是将最有选择性的列放在首位 在索引中。
从那时起,将最有区别的条目放在索引中的第一位是不正确的 将使索引更小或更高效。好像会,但不会。
带索引 密钥压缩,有一个令人信服的论据可以采用另一种方式,因为它可以使索引 更小。但是,如前所述,它应该由您使用索引的方式决定。
【讨论】:
您将索引压缩信息作为附注,但不应忽略它。在很多情况下,压缩索引是一个绝妙的主意。 @Craig:我可以看到列排序如何影响索引压缩,但反过来会不会起作用(低基数的前导列导致重复的、可压缩的前缀)?跨度> Tom 说对于 Oracle 5 asktom.oracle.com/pls/asktom/…【参考方案2】:使用索引时可以从右到左省略列,即当您在col_a, col_b
上有索引时,您可以在WHERE col_a = x
中使用它,但不能在WHERE col_b = x
中使用它。
想象有一个电话簿,它按名字排序然后按姓氏排序。
至少在欧洲和美国,名字的选择性远低于姓氏,因此查找名字不会缩小结果集的范围,因此仍有很多页面需要检查正确的姓氏。
【讨论】:
+1。如果前导列丢失,您仍然可以使用索引,但这将是全索引扫描(或索引跳过扫描),效率并不高(但仍可能比全表扫描更好)。跨度> 不过,这并没有回答关于选择性的部分。 我认为至少在欧洲和美国,名字的选择性比姓氏的选择性低得多,所以按名字在前的索引不会有太大帮助。 AndrewKR,是的,但这取决于在最左边指定最多选择列的索引。如果您将其添加到您的答案中,我会给您 +1。 @PerformanceDBA 我不太明白你的意思。你能详细说明一下吗?【参考方案3】:索引中列的顺序应由您的查询决定,而不是任何选择性考虑因素。如果你在 (a,b,c) 上有一个索引,并且你的单列查询大部分都是针对 c 列,然后是 a,那么在索引定义中按照 c,a,b 的顺序放置它们以获得最佳效率. Oracle 更喜欢使用索引的前沿进行查询,但可以在效率较低的访问路径(称为跳过扫描)中使用索引中的其他列。
【讨论】:
【参考方案4】:您的索引越有选择性,研究就越快。
想象一下电话簿:您可以通过姓氏快速找到某人。但是,如果您有很多人的姓氏相同,那么您将持续更多的时间通过每次查看名字来寻找该人。
所以你必须首先给出最具选择性的列,以尽可能避免这个问题。
此外,您应该确保您的查询正确使用了这些“选择性标准”。
【讨论】:
+1。这是完全正确的。假设已经完成,(AndrewKR) 列可以从右向左删除。以上是关于多列索引列顺序的主要内容,如果未能解决你的问题,请参考以下文章