适用于: SQL Server
Azure SQL 数据库
Azure Synapse Analytics
分析平台系统 (PDW)
WideWorldImportersDW 旨在展示适用于数据仓库和分析的 SQL Server 的许多关键功能。 下面是 SQL Server 特性和功能的列表,以及它们如何在 WideWorldImportersDW 中使用的说明。
PolyBase
[适用于 SQL Server(2016 及更高版本)]
PolyBase 用于将 WideWorldImportersDW 的销售信息与有关人口统计的公共数据集相结合,以了解哪些城市可能有兴趣进一步扩张销售。
若要在示例数据库中使用 PolyBase,请确保已安装 PolyBase,并在数据库中运行以下存储过程:
EXECUTE [Application].[Configuration_ApplyPolyBase]
这将创建一个外部表 dbo.CityPopulationStatistics
,该表引用一个公共数据集,该数据集包含 Azure Blob 存储中托管的美国各大城市的人口数据。 建议查看存储过程中的代码以了解配置过程。 如果要在 Azure Blob 存储中托管你自己的数据,使其免于常规公共访问,则需要执行其他配置步骤。 以下查询可从该外部数据集返回数据:
SELECT
CityID, StateProvinceCode, CityName,
YearNumber, LatestRecordedPopulation
FROM
dbo.CityPopulationStatistics;
为了了解哪些城市可能有兴趣进一步扩张,以下查询将研究城市增长率,并返回增长显著的前 100 个城市,以及广域导入商在哪些地方没有销售网点。 查询涉及远程表 dbo.CityPopulationStatistics
与本地表 Dimension.City
之间的联接,以及涉及本地表 Fact.Sales
的筛选器。
WITH PotentialCities
AS
(
SELECT cps.CityName,
cps.StateProvinceCode,
MAX(cps.LatestRecordedPopulation) AS PopulationIn2016,
(MAX(cps.LatestRecordedPopulation) - MIN(cps.LatestRecordedPopulation)) * 100.0
/ MIN(cps.LatestRecordedPopulation) AS GrowthRate
FROM dbo.CityPopulationStatistics AS cps
WHERE cps.LatestRecordedPopulation IS NOT NULL
AND cps.LatestRecordedPopulation <> 0
GROUP BY cps.CityName, cps.StateProvinceCode
),
InterestingCities
AS
(
SELECT DISTINCT pc.CityName,
pc.StateProvinceCode,
pc.PopulationIn2016,
FLOOR(pc.GrowthRate) AS GrowthRate
FROM PotentialCities AS pc
INNER JOIN Dimension.City AS c
ON pc.CityName = c.City
WHERE GrowthRate > 2.0
AND NOT EXISTS (SELECT 1 FROM Fact.Sale AS s WHERE s.[City Key] = c.[City Key])
)
SELECT TOP(100) CityName, StateProvinceCode, PopulationIn2016, GrowthRate
FROM InterestingCities
ORDER BY PopulationIn2016 DESC;
聚集列存储索引
(示例的完整版本)
聚集列存储索引 (CCI) 用于所有事实数据表,以减少存储占用空间并提高查询性能。 使用 CCI 时,事实数据表的基本存储使用列压缩。
非聚集索引在聚集列存储索引之上使用,以促进主键和外键约束。 添加这些约束是出于谨慎 - ETL 进程从 WideWorldImporters 数据库获取数据,而该数据库具有强制完整性的约束。 移除主键和外键约束及其支持索引会减少事实数据表的存储占用。
数据大小
示例数据库的数据大小有限,便于下载和安装示例。 但是,若要查看列存储索引的实际性能优势,需要使用更大的数据集。
可以运行以下语句,通过插入另外 1200 万行示例数据来增加 Fact.Sales
表的大小。 这些行都插入 2012 年,因此不会干扰 ETL 进程。
EXECUTE [Application].[Configuration_PopulateLargeSaleTable]
此语句需要大约 5 分钟才能运行。 若要插入超过 1200 万行,请将所需的行数作为参数传递给此存储过程。
若要比较有无列存储的查询性能,可以删除和/或重新创建聚集列存储索引。
删除索引:
DROP INDEX [CCX_Fact_Order] ON [Fact].[Order]
重新创建:
CREATE CLUSTERED COLUMNSTORE INDEX [CCX_Fact_Order] ON [Fact].[Order]
分区
(示例的完整版本)
数据仓库中的数据大小可能会非常大。 因此,最佳做法是使用分区来管理数据库中大型表的存储。
所有较大的事实数据表都按年份进行分区。 唯一的例外是 Fact.Stock Holdings
,该表不是基于日期,与其他事实数据表相比,数据大小有限。
用于所有已分区表的分区函数是 PF_Date
,所使用的分区方案是 PS_Date
。
内存中 OLTP
(示例的完整版本)
WideWorldImportersDW 使用 SCHEMA_ONLY 内存优化表作为临时表。 所有 Integration.
*_Staging
表都是 SCHEMA_ONLY 内存优化表。
SCHEMA_ONLY 表的优点是它们不被记录,并且不需要任何磁盘访问。 这提高了 ETL 进程的性能。 由于这些表不被记录,因此如果发生故障,其内容会丢失。 但是,数据源仍可用,因此,如果发生故障,只需重启 ETL 进程即可。