如何将 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=?
将这些列(考虑到基数混合)配对作为复合索引有什么好处吗?如果是这样,遵循的逻辑是什么?
我已经理解 this explanation 但它是针对 SQL 服务器的,它的行为可能会有所不同。
是否值得做覆盖索引而不是单独的小复合索引?
复合索引的列顺序重要吗?即:
-- 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);
- 这个索引有用吗?
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设计索引时,首先写出所有查询。
更多讨论:
这个问题涉及到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=?
将这些列(考虑到基数混合)配对作为复合索引有什么好处吗?如果是这样,遵循的逻辑是什么? 我已经理解 this explanation 但它是针对 SQL 服务器的,它的行为可能会有所不同。
是否值得做覆盖索引而不是单独的小复合索引?
复合索引的列顺序重要吗?即:
-- 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);
- 这个索引有用吗?
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设计索引时,首先写出所有查询。
更多讨论: