Cyn*_*ker 5 data-warehouse database-design sql-server columnstore star-schema
我在我的报告数据库中使用 MS SQL Server 2016 聚集列存储索引(我们称之为 CCI)。
在最初的设计中,我考虑的是星型模式,但后来我开始使用 CCI。现在我放弃了许多维度表,转而将字符串直接展平到“事实”表中。我保留维度表的唯一地方是当该维度具有频繁更改的属性并且要求使更改的属性适用于所有历史记录时。我做了这么多让一位拥有更多 DW 经验但没有空闲时间探索 CCI 的同事感到沮丧。
似乎作为单独列存储在磁盘上的平面表(以及提供的大规模压缩)根本不需要很窄。使用 CCI 时,何时还需要维度表?
Joe*_*ish 10
我认为您的问题不适用于任何支持列式存储的 RDBMS。我是从 SQL Server 的角度写我的答案,大多数原因取决于特定于 SQL Server 的实现细节。
使用 CCI 时,何时还需要维度表?
1.维度表的变化量使得更新CCI事实表不切实际
对于 5 亿行的事实表,如果某些维度列以不幸的方式更改,您可能需要更新 CCI 中的数亿行。我知道这样做的唯一实用方法是重写整个表或执行删除 + 插入。对于删除 + 插入方法,您可能需要将所有列的数据写入暂存区,等待串行删除查询完成(除非您可以按分区删除),读取所有行的所有列对于可能包含需要更改的行的行组,依此类推。编码可能很麻烦,转换数据也很昂贵。随着事实表变宽,问题会变得更糟。
2. 由于内存限制,字符串列的长度和数量使得 CCI 压缩不切实际
根据您构建 CCI 的方式,对字符串列的内存授予请求可能会失控。例如,列REBUILD的 aVARCHAR(8000)请求每个 DOP 6.5 GB 并随着列长度缩小。CCI 插入的内存授予请求超时时间为 25 秒(据我所知,无法更改此设置)。这意味着如果您没有足够的内存来执行压缩,您的某些 CCI 插入查询可能会开始直接写入增量存储(以及死锁和其他坏事)。
3. 您的 ETL 或维护流程并非旨在防止或清理增量存储
您在问题中提到了“大规模压缩”,但增量存储中的数据并未压缩。如果您的 ETL 过程创建了一个堆,然后将该数据压缩为列存储格式,那么您可能会使用比以往更多的临时空间来进行暂存。如果您对分区表进行大量并行插入,您最终可能会得到数千个或更多数据不会被压缩的增量存储,等等。
4.维度表有很多独特的长字符串
SQL Server 2016 限制为每列 16 MB 字典大小。如果一列有太多唯一值,那么您可能会超过该限制,并且由于字典压力,行组将被拆分。将字符串列添加到现有 CCI 事实表会导致压缩行组变小,这会降低压缩的有效性和查询性能。