多列索引如何在oracle中运行?

kar*_*ara 3 oracle indexing

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

| Company | Store | Sku | ..OtherColumns.. | 
|       1 |     1 | 123 | ..               | 
|       1 |     2 | 345 | ..               | 
|       3 |     1 | 123 | ..               |
Run Code Online (Sandbox Code Playgroud)

脚本

大多数时候company,store和sku将用于SELECT行:

SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;
Run Code Online (Sandbox Code Playgroud)

..但有时候公司在访问桌子时将无法使用.

SELECT * FROM stock s WHERE s.store = 1 AND s.sku = 123;
Run Code Online (Sandbox Code Playgroud)

..有时所有文章都会被选中用于商店.

SELECT * FROM stock s WHERE s.company = 1 AND s.store = 1;
Run Code Online (Sandbox Code Playgroud)

问题

如何正确索引表?

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

如果WHERE条件没有公司,是否会使用索引"Store,Sku,Company"?

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

Con*_*ald 5

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

WHERE s.company = 1 AND s.store = 1 AND s.sku = 123;
Run Code Online (Sandbox Code Playgroud)

可以从索引中受益

WHERE s.store = 1 AND s.sku = 123;
Run Code Online (Sandbox Code Playgroud)

不太可能受益(但见下文脚注)

WHERE s.company = 1 AND s.store = 1;
Run Code Online (Sandbox Code Playgroud)

可以从索引中受益.

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

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

脚注:有一个称为"跳过扫描"的东西,即使您没有指定前导列,我们也可以从索引中获取值,但是通常只会看到那些前导列中的不同值的数量低.