Sql server 事实表分区:如何在ETL中处理更新?

Sql server 事实表分区:如何在ETL中处理更新?,sql-server,sql-server-2008,ssis,etl,partitioning,Sql Server,Sql Server 2008,Ssis,Etl,Partitioning,我们正在尝试为数据仓库事实表实现表分区,数据仓库事实表包含大约4亿行。我们的ETL从上一次加载向后50天从源系统获取数据(新行、修改行,基于源系统时间戳)。因此,在每个ETL周期中,都会有新行进入,也会有旧行更新事实表中相应的行。其思想是在事实表中插入新行并更新修改后的行 分区列将是date(int,yyyyymmdd),我们正在考虑按月分区 据我所知,表分区将简化我们的插入。我们可以拆分最近的分区来创建一个新的空闲分区,将新行加载到一个临时表中(使用日期约束,例如最近一个月),然后使用分区切换

我们正在尝试为数据仓库事实表实现表分区,数据仓库事实表包含大约4亿行。我们的ETL从上一次加载向后50天从源系统获取数据(新行、修改行,基于源系统时间戳)。因此,在每个ETL周期中,都会有新行进入,也会有旧行更新事实表中相应的行。其思想是在事实表中插入新行并更新修改后的行

分区列将是date(int,yyyyymmdd),我们正在考虑按月分区


据我所知,表分区将简化我们的插入。我们可以拆分最近的分区来创建一个新的空闲分区,将新行加载到一个临时表中(使用日期约束,例如最近一个月),然后使用分区切换操作将新行“移动”到分区事实表中。但是我们如何处理修改后的行,这些行应该更新事实表中的相应行?这些行可以包含上个月的数据。分区开关在这里有用吗?通常,
INSERT
UPDATE
行由ETL工具(例如,在我们的例子中是SSI)或
MERGE
语句确定。在这种情况下分区是如何工作的?

这里切换没有帮助

也许您可以在不同范围的行上使用多个线程并发执行更新。那可能会加快速度。小心不要触发锁升级,这样可以获得良好的并发性


还要确保更新的行主要是按照聚集索引的升序排序的。这有助于磁盘IO(这项技术可能不适用于多线程)。

我将再看一看设计,并尝试找出是否有办法解决更新问题。以下是更新事实表的一些含义:

性能:更新是完全记录的事务。大型事实表也有很多数据要读和写

多维数据集:更新事实表需要重新处理受影响的分区。随着事实表的不断增长,多维数据集的处理时间也将继续增加

预算:快速存储非常昂贵。更新大型事实表需要大量的快速读写

纯粹主义理论:除非初始值是一个错误(即用户输入了15000美元而不是1500美元),否则不应该更改事实表。任何非错误场景都将更改最初记录的事务

什么在改变?变化的片段真的是维度的属性吗?如果是,是否可以将其移动到维度,并使用缓慢变化的维度类型任务处理更改

另一种可能性是,这可以通过抵消交易来实现吗?例如:

初始发票金额为10.00美元。会计部后来增加了1.25美元的税款,然后向客户开出了11.25美元的账单。插入1.25美元的记录,而不是将值更新为11.25美元。发票的总金额仍然是11.25美元,您可以执行一次最小日志插入,而不是一次完全日志更新

更新事实表不仅在理论上是个坏主意,而且随着事实表的增长,它变得非常昂贵且不可扩展。您将读取和写入更多数据,需要存储子系统提供更多IOPS。当您准备好进行分析时,多维数据集处理会带来更多问题

您还必须不断向管理层证明,为什么数据仓库需要如此多的IOPS。对于不断变化的“事实”表,需要所有这些IOPS是否有商业价值/正当性


如果无法找到解决事实表更新问题的方法,至少要建立一个截止点,将数据确定为只读。否则,您将永远无法缩放。

更新事实记录的原因与事实中的非标识属性一样多。除非您计划先“删除”再“插入”,否则无法避免更新。您不能简单地说“将度量增量记录为新事实”