如何将 low/high 基数列配对为复合索引?

How to pair low/high cardinality columns as composite indexes?

这个问题涉及到Oracle DB,所以如果有一般性的答案我想知道。因为我正在丢弃来自 Derby/MySQL 和其他数据库的有关此主题的信息。

假设我有几个查询在其 WHERE 子句中使用以下列:

Column | Cardinality | Selectivity
_______|__________________________
A      | low         | low
B      | high        | low
C      | low         | low
D      | high        | high
E      | low         | low
F      | low         | low
-- Queries
SELECT * FROM T WHERE A=? AND B=? 
SELECT * FROM T WHERE A=? AND B=? AND C=?
SELECT * FROM T WHERE A=? AND C=?
SELECT * FROM T WHERE A=? AND C=? AND D=?
SELECT * FROM T WHERE A=? AND E=? AND F=?
  1. 这些列(考虑到基数混合)配对作为复合索引有什么好处吗?如果是这样,遵循的逻辑是什么? 我已经理解 this explanation 但它是针对 SQL 服务器的,它的行为可能会有所不同。

  2. 是否值得做覆盖索引而不是单独的小复合索引?

  3. 复合索引的列顺序重要吗?即:

-- Regardless the column order on the table creation.
CREATE INDEX NDX_1 ON T (A, C);
-- Versus:
CREATE INDEX NDX_1 ON T (C, A);
  1. 这个索引有用吗?
CREATE INDEX NDX_2 ON T(E, F); -- (low + low) Ignoring 'A' column.

一些事情并记住这些是一般性的

  • 通常只能使用索引的前导部分。这么看 在你的例子中

    如果您在 ( A, B, C ) 上有一个索引并且您在 A 上有一个谓词并且 C,那么只能使用A上的索引。现在有一些情况 其中索引 的 non-leading 部分可以 使用;你会看见 这在执行计划中作为 SKIP-SCAN 操作,但它们是 经常sub-optimal。所以你可能想要 (A, C) 和 ( C, A )

  • 覆盖索引可能很有用,如果您不投影索引中的列以外的列。

  • 一般来说,如果列的选择性较低,您通常不需要或不需要索引。但是,您可能有两根色谱柱,它们各自的选择性较低,但组合使用时选择性较高。 (其实这是在维度模型中进行位图索引/星形变换的前提)

  • 如果 multi-column 索引有用,您可能希望将选择性最低的列放在首位并启用索引压缩。在某些情况下,索引压缩可以节省大量 space,并且开销很小 CPU。

最后,一份 SQL 监控报告将帮助您优化 sql 语句,当它涉及到 运行 时。

最佳处理所有 5 种情况的最小索引数:

(A, B, C)  -- in exactly this order
(A, C, D)  -- in exactly this order
(A, E, F)  -- in any order

如果您再添加一个SELECT,则所有投注均无效。

什么时候有(A, C)(C, A)?...

  • 每个处理仅使用第一列的情况。
  • 前者最适合WHERE A=1 AND C>5;后者不是。 (等)注意:= 与某种“范围”测试很重要。

为table设计索引时,首先写出所有查询。

更多讨论: