1

考虑以下形式的事实表:

CREATE TABLE Fact1
(
    Dim1 int NOT NULL,
    Dim2 int NOT NULL,
    Dim3 int NOT NULL,
    Data1 int NOT NULL,
    Data2 int NOT NULL
    ...
)

Fact1在每个维度上都有一个列索引。Dim1假定为时间维度,粒度细至小时范围(例如,2011 年 3 月 12 日下午 2 点到 6 点之间)。在 Dim1中包含Dim2Dim3覆盖列是否有用?或者同样在其中任何一个上?

更一般地说,将其他维度表 FK 列作为给定维度的索引上的覆盖列包含在内是否有用?

注意:对于事实表,我们假设不需要唯一标识给定的事实。因此,缺少主键或代理键。(Dim1, Dim2, Dim3) 始终是唯一的元组来保证唯一性。

4

1 回答 1

4

我将尝试回答更一般的问题 - “将其他维度表 FK 列作为给定维度的索引上的覆盖列包含在内是否有用?”

是的。如果您有大量执行 COUNT() 之类的操作的查询,其中覆盖索引允许您扫描较小的数据集,那么添加这些其他维度可能很有价值。

SELECT Dim1, Dim2, count(*)
from Fact1
group by Dim1, Dim2

只有 Dim1 或 Dim2 上的索引,您最终不得不做一个 FTS 来做这个计数。这可能完全没问题。全面扫描并不总是坏事。但是,如果你想加快这类查询的速度(比如事实表很宽),那么在 Dim1 上添加一个 B-tree 索引,Dim2 将允许 DBMS 去索引进行计数,而不必去到表数。请注意,它仍然会对索引进行全盘扫描,这可能只比全表扫描快一点。

一般来说,我怀疑您是否会看到这么多的性能提升,因为无论如何您仍在扫描索引的所有行,除非索引明显小于表,否则您可能不会得到很大的改进。

由于它是一个事实表,因此在维度上覆盖索引会有所帮助的唯一查询是仅查询维度本身时。任何使用事实的东西都需要进行索引扫描,然后在表中查找实际数据。

我可能只是在 dims 上为使用键(和连接)的查询构建 B-tree 索引,然后在系统运行一段时间并识别出常见查询时根据需要添加其他索引。

我能想到的另一种情况是,像这样的“覆盖”索引可能有助于加快查询速度,即当您有关注特定维度组合的查询时,您只需要那些特定的行。

SELECT Dim1, Dim2, Data1, Data2
  FROM Fact1 
 WHERE Dim1 = @A and Dim2 = @B;

如果您有一个 b-tree 索引,Dim1, Dim2而不仅仅是,您可能会看到非常轻微的性能提升Dim1,因为您扫描索引以查找 WHERE 子句中的所有项目,然后获取您的事实数据。

于 2012-06-15T19:08:10.707 回答