【问题标题】:How does a multi-column index work in oracle?oracle 中的多列索引是如何工作的?
【发布时间】:2018-06-15 08:29:16
【问题描述】:

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

表格

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

场景

大多数时候公司、商店和 sku 将用于选择行:

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 条件没有公司,是否会使用索引“Company, Store, Sku”?

【问题讨论】:

  • 您评估它的方式是获取有代表性的数据负载,在每一列上添加一个单独的索引,然后查看为您的查询生成的计划。
  • 如果您构建三个单独的索引,那么 Oracle 只会在极少数情况下将它们组合在一起 - 除非您创建 Bitmap-Indexes,否则它们会被组合在一起。但是,它们还有其他缺点。否则谷歌索引跳过扫描

标签: oracle indexing


【解决方案1】:

您可以将索引键在概念上视为所有列的“连接”,通常您需要该键的前导元素才能从索引中受益。所以对于(公司,商店,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) 将“足够好”以满足所有三个,但这取决于数据的分布。但您的想法是正确的,即从尽可能少的索引中获取尽可能多的价值。

脚注:有一种叫做“跳过扫描”的东西,即使您没有指定前导列,我们也可以从索引中获取值,但您通常只会看到那些前导列很低。

【讨论】:

    【解决方案2】:

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

    第二——什么是数据结构?您在每种情况下都有存储列 - 我可以想象存储上的过滤数据将源数据剖析到足以满足您的程度的情况。

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

    (商店、sku、公司)

    (商店、公司)

    (商店、公司、sku)

    (商店,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 开始,尝试在纸上画出它的行为或编写简单的程序来管理简化版本。然后读取数据库中的索引 - 任何数据库都足够好。

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 2019-07-08
      • 2020-05-06
      • 2011-04-03
      • 2018-11-27
      • 1970-01-01
      相关资源
      最近更新 更多