多列索引如何在oracle中工作?

时间:2018-06-15 08:29:17

标签: oracle indexing

我正在建立一个表来管理一些文章:

| Company | Store | Sku | ..OtherColumns.. | 
|       1 |     1 | 123 | ..               | 
|       1 |     2 | 345 | ..               | 
|       3 |     1 | 123 | ..               |

方案

大部分时间公司,商店和sku将用于SELECT行:

SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;

..但有时候访问该表时公司将无法使用。

SELECT * FROM stock s WHERE s.store = 1 AND s.sku = 123;

..有时会为商店选择所有文章。

SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1;

问题

如何正确索引表格?

我可以添加三个索引 - 每个选择一个,但我认为oracle应该很聪明地重用其他索引。

如果WHERE条件没有公司,是否会使用Index“Store,Sku,Company”?

如果WHERE条件没有公司,是否会使用索引“公司,商店,Sku”?

2 个答案:

答案 0 :(得分:5)

您可以将索引键视为概念上的“串联”键。在所有列中,通常需要具有该键的前导元素才能从索引中获益。所以对于(公司,商店,sku)的索引,那么

WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;

可能会从索引中受益

WHERE s.store = 1 AND s.sku = 123;

不太可能受益(但请参阅下面的脚注)

WHERE s.company = 1 AND s.store = 1;

可能会从索引中受益。

在所有情况下,我说"潜在"等等,因为它是优化器的成本决策。例如,如果我只有(比方说)2家公司和2家商店,那么对公司和商店进行查询,而可能使用索引可能更适合而不是这样做,因为要查询的信息量仍然是表格大小的一小部分。

在您的示例中,可能是(store,sku,company)上的索引将足够好"满足所有三个,但这取决于数据的分布。但是你正在思考正确的方法,即从尽可能少的索引中获取尽可能多的价值。

脚注:有一种叫做"跳过扫描"即使您没有指定前导列,我们也可以从索引获取值,但是通常只会看到那些前导列中的不同值的数量很少。

答案 1 :(得分:0)

首先 - 你需要索引吗?索引不是免费的。如果你的桌子很小,或许你根本不需要索引。

第二 - 什么是数据结构?你在每个场景中都有商店专栏 - 我可以想象商店中的过滤数据分析源数据的程度足以让你足够好。

但是,如果您希望获得最大的合理性能优势,则需要两个:

(商店,sku,公司)

(商店,公司)

(商店,公司,sku)

(store,sku)

Would an Index "Store, Sku, Company" be used if the WHERE-condition has no company?

Would an Index "Company, Store, Sku" be used if the WHERE-condition has no company?

可能不是,但我可以想象它可能发生的场景(不是索引搜索操作,这实际上是索引的主要目的)

您按列顺序剖析数据。因此,您按第一个元素对数据进行分组,并按照第一列排序顺序对它们进行排序,然后在这些组中按第二个元素的相同方式进行分组 因此,当您不在过滤中使用索引的第一个元素时,数据库必须访问所有"子组"反正。

我建议一般阅读索引。从https://en.wikipedia.org/wiki/B-tree开始,尝试绘制它在纸上的行为或编写简单程序来管理简化版本。然后阅读数据库中的索引 - 任何数据库都足够好。