我正在构建一个表来管理一些文章:
| Company | Store | Sku | ..OtherColumns.. | 
|       1 |     1 | 123 | ..               | 
|       1 |     2 | 345 | ..               | 
|       3 |     1 | 123 | ..               |
大多数时候company,store和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条件没有公司,是否会使用索引"Store,Sku,Company"?
如果WHERE条件没有公司,是否会使用索引"公司,商店,Sku"?
您可以将索引键视为概念上是所有列的"串联",并且通常需要具有该键的前导元素才能从索引中获益.那么对于(公司,商店,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)上的索引"足够好"以满足所有三个索引,但这取决于数据的分布.但是你正在思考正确的方法,即从尽可能少的索引中获取尽可能多的价值.
脚注:有一个称为"跳过扫描"的东西,即使您没有指定前导列,我们也可以从索引中获取值,但是通常只会看到那些前导列中的不同值的数量低.