合并分区
对于沿日期分区的多维数据集,它的分区的数量会随时间流逝而增长。如前面所述,分区数量增加到一定程度后,理论上存在着一个查询性能开始降低的点。我们测试了包括 500 个以上分区的开发项目,但还没有达到过这个极限。由于过多分区的其他缺点,例如源数据操作缓慢等,将给管理数据库带来更多的困难,系统管理员在达到该极限之前往往就已不能忍受它了。
通过 DSO 和分析管理器,分析服务支持合并分区的功能。合并两个分区时,一个分区的数据将合并到另一个分区中。两个分区必须具有相同的存储模式和聚合计划。合并完成后,第一个分区被丢弃,第二个分区则包含合并的数据。合并处理仅发生在多维数据集数据上;合并过程中不访问数据源。两个分区的合并过程的效率很高。
如果系统设计包括合并的分区,合并过程应该通过编程进行,而不是通过分析管理器。合并分区很简单,和其他 DSO 操作一样只需要几行代码。分区合并系统必须负责验证最终合并的分区包含用于源筛选的精确元数据信息,以确保必要时可以重新处理分区。分区合并过程正确地更改分区片定义,也尽可能合并筛选定义。但合并过程不要求从相同的表或数据源填充两个分区,合并两个不能被重新填充的分区是可能的。
第二个要考虑的问题是:与所有分区一样,已合并的分区不能被重新命名。
通过使用以下良好的系统设计方法可以避免这些问题:
使用清晰的命名约定。
遵循一致的分区合并计划。
匹配分区多维数据集和关系分区时要小心,或不对关系型数据仓库进行分区。
例如,考虑按星期分区数据的“销售额”多维数据集。本周按日进行分区,然后在本周末合并。将分区命名为 Sales_yyyymmdd,其中名称中的日期是分区中数据的第一天。2000 年 11 月,我们将会有 Sales_20001105、Sales_20001112、Sales_20001119 和 Sales_20001126 周分区。下周里,我们通过 Sales_20001209 创建和处理 Sales_20001203、Sales_20001204 等。在星期天的处理窗口期间(那时系统使用率很低),我们可以把从 20001204 到 20001209 合并至 Sales_20001203,仅留下周分区。或者,您可以通过新建一个有您想要的名称的空分区,将其他分区合并进去,从而有效地重新命名一个分区。
丢弃旧的分区
删除按日分区的多维数据集中的旧数据与丢弃最老的分区(集)一样简单。与我们讨论过的其他操作相似,这个过程应该通过编程来管理,而不是通过分析管理器个别进行。如果您理解了这一点,您会乐意花几小时编写和测试这个模块。
总结
建议中到大型分析服务多维数据集(包含 10 亿行以上的事实)使用本地分区。分析服务数据库的查询性能可以通过分区得到改善。维护分区多维数据集很容易,尤其在从多维数据集中丢弃旧数据的情况下。然而,对多维数据集进行分区需要一个管理这些分区的应用程序。
在概念上,在关系型数据仓库中分区与在分析服务中分区相似。和分析服务一样,必须创建应用程序来管理关系分区。有关应在关系型数据仓库中进行分区的观点并不是强制性的。分区解决了某些维护问题,例如修剪旧数据,但这是以系统复杂性为代价的。与建立良好索引的单个表相比,查询性能并没有得到改善。
分析服务和 SQL Server 关系型数据库都支持分布式分区,即分区驻留在不同的服务器上。关于分析服务中分布式分区的问题将留到另一篇文章中讨论。我们不推荐为支持特定查询的 SQL Server 2000 数据仓库系统划分分布关系分区。
使用大量分区可改善分区多维数据集的查询性能。大型多维数据集的开发人员应该考虑按多个矢量进行分区,以尽可能改善用户查询的选择性,同时通过提供并行处理的机会来改善处理性能。
极力推荐对大型分析服务系统进行分区。尽管对于某些特定的仓库维护问题,对关系型数据仓库进行分区是有效而性能良好的解决方案,但通常不推荐您这样做。
附录:复制分区的 VBScript 代码示例
/*********************************************************************
'' 文件:ClonePart.vbs
''
''说明:根据 FoodMart 2000 Sales 多维数据集中的最新分区,
'' 这个脚本示例会在该多维数据集中创建新的分区。
'' 此脚本的目的是显示用于复制一个分区的 DSO 呼叫类型。
'' 产生的分区将经过处理,但多维数据集中
'' 不会增加任何数据
''
'' 脚本用户可在运行脚本和查看结果后
'' 删除产生的分区。
''
'' 参数: 无
''*********************************************************************/
Call ClonePart
Sub ClonePart()
On Error Resume Next
Dim intDimCounter, intErrNumber
Dim strOlapDB, strCube, strDB, strAnalysisServer, strPartitionNew
Dim dsoServer, dsoDB, dsoCube, dsoPartition, dsoPartitionNew
'' 初始化服务器、数据库和多维数据集名变量。
strAnalysisServer = "LocalHost"
strOlapDB = "FoodMart 2000"
strCube = "Sales"
'' VBScript 不支持直接使用枚举常量。.
'' 然而,可定义常量以取代枚举。
Const stateFailed = 2
Const olapEditionUnlimited = 0
'' 连接到分析服务器。
Set dsoServer = CreateObject("DSO.Server")
dsoServer.Connect strAnalysisServer
'' 如果连接失败,则结束枚举。
If dsoServer.State = stateFailed Then
MsgBox "Error-Not able to connect to ''" & strAnalysisServer _
& "'' Analysis server.", ,"ClonePart.vbs"
Err.Clear
Exit Sub
End if
'' 某些分区管理功能只有在分析服务的
'' Enterprise 和 Developer 发行版中
'' 才可使用。
If dsoServer.Edition <> olapEditionUnlimited Then
MsgBox "Error-This feature requires Enterprise or " & _
"Developer Edition of SQL Server to " & _
"manage partitions.", , "ClonePart.vbs"
Exit Sub
End If
'' 确定数据库中有有效的数据源。
Set dsoDB = dsoServer.mdStores(strOlapDB)
If dsoDB.Datasources.Count = 0 Then
MsgBox "Error-No data sources found in ''" & _
strOlapDB & "'' database.", , "ClonePart.vbs"
Err.Clear
Exit Sub
End If
'' 查找多维数据集。
If (dsoDB.mdStores.Find(strCube)) = 0 then
MsgBox "Error-Cube ''" & strCube & "'' is missing.", , _
"ClonePart.vbs"
Err.Clear
Exit Sub
End If
'' 将 dsoCube 变量设置到所要的多维数据集。
Set dsoCube = dsoDB.MDStores(strCube)
'' 查找分区
If dsoCube.mdStores.Count = 0 Then
MsgBox "Error-No partitions exist for cube ''" & strCube & _
"''.", , "ClonePart.vbs"
Err.Clear
Exit Sub
End If
'' 将 dsoPartition 变量设置到所要的分区。
Set dsoPartition = dsoCube.MDStores(dsoCube.MDStores.Count)
MsgBox "New partition will be based on existing partition: " _
& chr(13) & chr(10) & _
dsoDB.Name & "." & dsoCube.Name & "." & _
dsoPartition.Name, , "ClonePart.vbs"
'' 从数据源获得引用字符,因为
'' 不同的数据源使用不同的引用字符。
Dim sLQuote, sRQuote
sLQuote = dsoPartition.DataSources(1).OpenQuoteChar
sRQuote = dsoPartition.DataSources(1).CloseQuoteChar
''*********************************************************************
'' 根据所要的分区创建新分区。
''*********************************************************************
'' 创建新的暂时分区。
strPartitionNew = "NewPartition" & dsoCube.MDStores.Count
Set dsoPartitionNew = dsoCube.MDStores.AddNew("~temp")
'' 从所要的分区复制属性到
'' 新分区。
dsoPartition.Clone dsoPartitionNew
'' 将 "~temp" 分区名更改为
'' 想要供新分区使用的名称。
dsoPartitionNew.Name = strPartitionNew
dsoPartitionNew.AggregationPrefix = strPartitionNew & "_"
'' 设置新分区事实表。
dsoPartitionNew.SourceTable = _
sLQuote & "sales_fact_dec_1998" & sRQuote
'' 设置新分区的 FromClause 和 JoinClause
'' 属性。
dsoPartitionNew.FromClause = Replace(dsoPartition.FromClause, _
dsoPartition.SourceTable, dsoPartitionNew.SourceTable)
dsoPartitionNew.JoinClause = Replace(dsoPartition.JoinClause, _
dsoPartition.SourceTable, dsoPartitionNew.SourceTable)
'' 将受影响的层次和维度的 SliceValue 属性
'' 更改为所要的值,以更改新分区使用的
'' 数据切片定义。
dsoPartitionNew.Dimensions("Time").Levels("Year").SliceValue = "1998"
dsoPartitionNew.Dimensions("Time").Levels("Quarter").SliceValue = "Q4"
dsoPartitionNew.Dimensions("Time").Levels("Month").SliceValue = "12"
'' 估计行数。
dsoPartitionNew.EstimatedRows = 18325
'' 添加另一筛选。SourceTableFilter 提供另外的
'' 机会,可将 WHERE 从句加入要填充的 SQL 查询。
'' 我们使用此筛选程序以确保新分区中未包含
'' 任何数据行。基于此示例代码的目的,我们不想
'' 更改 FoodMart 多维数据集中的数据。如果您想要新分区中
'' 看数据,请去掉此行。
dsoPartitionNew.SourceTableFilter = dsoPartitionNew.SourceTable _
& "." & sLQuote & "time_id" & sRQuote & "=100"
'' 将分区定义保存在元数据知识库中。
dsoPartitionNew.Update
''检查新分区结构的有效性。
IF NOT dsoPartitionNew.IsValid Then
MsgBox "Error-New partition structure is invalid."
Err.Clear
Exit Sub
End If
MsgBox "New partition " & strPartitionNew & " has been created and " _
& "processed. To see the new partition in Analysis Manager, you " _
& "may need to refresh the list of partitions in the Sales cube " _
& "of FoodMart 2000. The new partition contains no data.", , _
"ClonePart.vbs"
'' 下一语句已去掉,将处理分区。
'' 在实际分区管理系统中,这可能是一个单独的
'' 过程,可能由 DTS 管理。
'' dsoPartitionNew.Process
'' 清理。
Set dsoPartition = Nothing
Set dsoPartitionNew = Nothing
Set dsoCube = Nothing
Set dsoDB = Nothing
dsoServer.CloseServer
Set dsoServer = Nothing
End Sub
在SQL Server 2000数据仓库中使用分区
0
相关文章