我正在构建一个表来管理一些文章:
table
| 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”?
最佳答案
您可以在概念上将索引键视为所有列的“串联”,通常您需要该键的前导元素才能从索引中受益。因此,对于 (company,store,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) 上的索引“足够好”来满足所有三个要求,但这取决于数据的分布。但是您的想法是正确的,即从尽可能少的索引中获得尽可能多的值(value)。
脚注:有一种叫做“跳过扫描”的东西,即使您没有指定前导列,我们也可以从索引中获取值,但您通常只会看到这些前导列中不同值的数量低。
关于oracle - oracle中的多列索引是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50871774/