我有一个基本上像这样的源表:
- 员工守则
- 周开始日期
- 工作日 1
- 工作日 2
- 工作日 3
- 工作日 4
- 工作时间5
- 工作日 6
- 工作日 7
实际的表格每个工作日有大约 500 个编号的列(并没有真正计算它们 - 有各种各样的编号为 1-7 的字段,然后是另外一些编号为 1-25,乘以 7 的字段(不,那不是我的设计) ,目前大约有 38,600 行(每周增长)。
我有一个 SSIS 包试图规范化这些数据......目前看起来像这样:
每个“源”从同一个源表中选择一组编号的列,UNION ALL 组件将 7 个源合并为一个,产生大约 258,900 行。
工作流的其余部分添加一些计算列,查找代理键(例如EmployeeCode
用于查找EmployeeId
,然后计算日期并用于查找 a TimeId
),然后更新“修改”行和“新”行一个被插入到一个规范化的表中;未更改的行最终无处可去。
有没有更好的方法(例如,减轻内存压力)来规范化源数据?
没有完整的表定义,很难提供完美的答案。然而,为了在有限的重现中显示差异,使用非常少量的数据,我创建了以下测试平台:
下面我们比较两个查询;第一个使用我在SQLServerScience.com
CROSS APPLY
上详述的方法,第二个使用方法。UNION ALL
首先要注意的
CROSS APPLY
是, 更容易看。这已经让我很开心了。让我们检查两个变体的执行计划:
该
UNION ALL
变体扫描源表 7 次,而CROSS APPLY
使用单表扫描。通过使用交叉应用,我们#Winning。让我们添加更多数据:
在我的系统上,上面的代码生成了大约 85,000 行。这两个查询的计划现在是:
SQL Sentry Plan Explorer显示以下摘要信息,这些信息非常宝贵:
这表示 CPU 被更密集地使用
CROSS APPLY
,但是变体使用的 I/O 是其 7 倍UNION ALL
。