当先锋百科网

首页 1 2 3 4 5 6 7
SQL Server 2008
数据仓库查询性能
Sunil Agarwal and Torsten Grabs and Dr. Joachim Hammer
 
概览:
  • 星型联接查询优化
  • 分区表并行处理
  • ROW 和 PAGE 压缩
  • 分区对齐的索引视图

较前期同类产品相比,SQL Server 2008 将提供功能更为强大的关系数据仓库,但是您可能仍希望了解如何充分利用这项新技术来构建性能良好的数据仓库,以便对数十亿行的数据进行决策支持查询。或者您可能希望了解哪些功能将有助于您获取针对决策支持查询和报告的最佳查询性能,或者该新版本的 SQL Server ® 可实际带来哪种性能改进。
越接近实际产品发布,越会产生许多问题。我们在此深入探讨 SQL Server 2008 中一些与性能相关的最重要数据仓库功能,希望能对您有所裨益。

逻辑数据库设计:维度建模
事务性业务线应用程序通常使用规范化数据库架构。关系数据仓库的逻辑数据库架构设计不太注重规范化。现在的许多关系数据仓库设计都使用维度建模方法,这种方法的流行得益于 Ralph Kimball 和 Margy Ross 合著的《The Data Warehouse Toolkit:The Complete Guide to Dimensional Modeling》。
如果经常与数据仓库打交道,您可能已经熟悉关系数据仓库的常见架构模式(如星型架构和雪花型架构)。维度建模将维度表与事实表区分开来。维度表存放主数据(如产品、客户、商店或国家),而事实表则存储事务性数据(如销售、订单、采购或利润)。
维度表和事实表是通过主键 (PK)/外键 (FK) 关系链接在一起的。您会发现许多数据仓库并未强行要求将 FK 约束作为降低存储要求的方法。这就节省了基础索引的存储开销,降低了事实表的维护成本。数据仓库中的维度表通常非常的小 — 一般最少几千行,最多几百万行。事实表则非常大,存放着上亿到十几亿行。因此,事实表的存储要求是逻辑设计的真正重点。
在确定应从维度表中选择哪个键来维护事实表/维度表关系时,这一大小因素也在考虑之内。基于维度业务键的组合键(表示维度所代表实体的实际标识符)通常包含多个列。请注意,对于事实表中的对应外键而言,这是个问题,因为会对每个事实表行重复这一多列组合键。
为此,一种常见的方法是使用小的代理键在事实表及其维度之间建立关系。代理键是一个整数型标识列,用作维度表的虚拟主键。事实表引用更小的代理键后,大型事实表的存储要求得以显著降低。 图 1 说明了使用维度表和代理键型事实表的维度建模数据仓库架构。
Figure 1  包含一个事实表和两个维度表的星型架构示例 (单击该图像获得较大视图)
雪花型架构设计将一个或多个维度散布到多个级别(例如,某个客户维度的客户、国家和地区),从而规范化数据中存在过度冗余的大型维度。各级别由单个表代表,从而使该架构呈雪花状。而星型架构设计则不将其任何维度散布到多个表内。星型架构形状象星星,其中维度表围绕四周,中心是事实表。
通过使用维度建模的星型架构或雪花型架构,决策支持查询采用以下典型模式:查询从事实表选择多个感兴趣的度量、通过代理键联接事实行和一个或多个维度、针对维度表的业务列应用筛选谓词、按一个或多个业务列分组,并统计在一段时间内从事实表检索的度量。以下即是该模式的示例,它有时也被称为星型联接查询:

物理设计
关系数据仓库中的许多 SQL 查询都遵循星型联接查询结构。然而,决策支持查询通常应时而变,因为决策者们总是希望通过新方法来更好地了解其基础业务数据。这就是数据仓库要面对大量临时查询的原因。这也使得决策支持查询和维度建模数据仓库架构的物理设计富有挑战性。
通过使用 SQL Server,数据仓库设计人员通常首先建立一个蓝图或物理设计,它可根据工作负载的变化进行精细调整。可根据您数据仓库环境的实际情况自由使用或更改该蓝图。如果是这样,请谨记数据库物理设计的最佳实践,如索引更新维护所引起的性能影响以及索引的存储要求。

事实表
蓝图设计旨在预计典型的星型查询形状并构建事实表的索引。事实表的聚集索引将多个维度代理键列(外键列)作为索引键。最常用的列应出现在索引键列表中。您可能希望确认它确实为工作负载中最常执行的查询提供了一个不错的访问路径。
此外,蓝图为事实表中的每个维度代理(外键)列创建了一个单列非聚集索引。从而为某一维度极具选择性的查询提供了一个高效访问路径。
聚集索引的目标是为提高工作负载中大部分查询的性能。非聚集索引组的目标是为特定客户或产品检索事实表度量的查询。这些非聚集索引可帮您提高效率,例如,您不必扫描事实表来检索单个客户的销售数据。

维度表
在对维度表应用蓝图设计时,需为每个维度表创建索引。它们包括针对维度代理键列的非聚集主键约束索引,以及针对维度实体业务键列的聚集索引。对于大型维度表,还应考虑增加针对高选择性谓词中常用列的非聚集索引。
聚集索引在数据仓库维护期间可提高提取、转换和加载 (ETL) 效率,而维护对于时间要求往往很严格。例如,通过缓慢地更改维度,现有行得到适当更新,同时尚未出现在维度中的行则附加到维度表。为成功达到目标,该访问模式要求在 ETL 期间维度表的查询和更新一切顺利。
要对利用 SQL Server 构建的关系数据仓库进行物理设计,我们提到的蓝图设计是个不错的起点。根据该典型关系数据仓库设置,我们可研究 SQL Server 2008 中包含的重要新功能。

星型联接查询优化
处理事实表通常是在维度建模关系数据仓库中执行星型联接查询时最大的开销。这一点显而易见,因为即使是高选择性的查询,从事实表检索的行数都远比从任何维度表检索出的要多得多。因此,针对事实表使用最好的访问路径对于实现良好的查询性能而言至关重要。
通过使用 SQL Server,查询优化器可自动从一组备选方案中选择开销最低的访问路径。在数据仓库环境中,主要目标是确保查询优化器为星型联接查询的执行计划选择最佳的备选访问途径。SQL Server 的查询优化器中使用多种功能自动提供性能良好的星型查询执行计划。
可将星型联接查询视为分成三个不同的类别(如 图 2 所示)。这几大类还有助于 SQL Server 引擎找出适用于这些查询的正确计划。SQL Server 所依据的主要概念是这些查询相对事实表的选择性。查询从事实表提取的行越少,越具选择性。事实表检索行的百分比用作这些查询类的直观区分标准。这些百分比代表来自典型客户部署的值,但它们并非用于生成访问路径定义的严格分界线。
Figure 2  星型联接查询的选择性范围 (单击该图像获得较大视图)
第一类为高选择性查询,最多处理事实表中 10% 的行。第二类为中等选择性,所包含的查询处理事实表行的 10% 到 75% 。第三类是低选择性查询,在事实表中处理的行超过 75%。图中的方框还着重指出了每个选择性类别中的基本查询执行计划选项。

基于选择性的计划选项
由于高选择性星型查询检索的事实表行通常不超过 10%,因此这些查询可随机访问事实表。所以,该类的查询计划主要依赖于嵌套循环联接以及对事实表的(非聚集)索引搜索和书签查询。由于它们对事实表执行随机 I/O,因此如果需要检索大部分事实表,可通过连续 I/O 获取更好的性能。由于从事实表检索的行数超过了一定数量,所以需要另一种查询计划。
由于中等选择性的星型查询会处理事实表中相当多的行,哈希联接和事实表扫描或事实表范围扫描通常是对事实表的首选访问路径。SQL Server 使用位图筛选器来改善这些哈希联接的性能。
图 3 显示了 SQL Server 如何使用这些位图筛选器来改善星型联接查询执行期间的联接性能。该图显示了针对 Product 和 Time 两个维度表的一个查询计划,这两个表通过代理键与事实表联接。查询针对两个维度表使用筛选谓词(如 WHERE 子句),以便只能有一行符合所有维度。两个联接运算符旁边的小红表格是这一特征的指示符。
Figure 3  减少了联接的星型联接查询计划 (单击该图像获得较大视图)
每个联接的联接实施都是哈希联接,它允许 SQL Server 从维度表将有关合格行的信息提取到两个维度表的联接减少信息中。图中的绿色方框代表联接减少信息数据结构。从底层维度表取得数据后,SQL Server 会在查询执行期间自动把这些数据结构移到处理事实表的运算符(如表扫描)。该运算符使用有关维度表行的信息来除去不满足维度联接条件的事实表行。
从事实表检索行后,SQL Server 在查询处理期间的前期就会剔除这些事实表行。这样,在查询计划的后续运算符中无需再处理已剔除的行,从而可节省 CPU 甚至磁盘 I/O 的开销。SQL Server 使用位图表示来有效表达查询执行期间的联接减少信息数据结构。

星型联接优化管道
优化过程使用标准的试探法来实现联接查询优化,以生成最初的一组查询执行计划备选方案。然后调用特殊的扩展项来生成其他查询计划备选方案。
对于数据仓库,扩展项会检测星型架构、雪花型架构以及星型查询模式,并评估查询相对事实表的选择性。如果架构和查询形式与模式匹配,SQL Server 会自动向计划空间添加更多的查询计划,然后基于开销的优化会对其进行处理以选择最有前景的查询执行计划。
在查询执行期间,SQL Server 还会监视联接减少在运行时的实际选择性。如果选择性发生变化,SQL Server 会动态重新排列联接减少信息数据结构,以便首先应用具有最大选择性的计划。

星型联接试探法
数据仓库的许多物理设计均遵循星型架构,但并不完全指定事实表和维度表之间的关系(例如之前提到的外键约束)。如果缺少明确指定的外键约束,SQL Server 必须依赖试探法来检测星型架构查询模式。可使用以下试探法来检测星型联接查询模式:
  1. 参与 n 元联接的最大表被视为是事实表。对于事实表的最小大小还有一些限制。例如,如果即使是最大的表也并未超过指定的大小,则不将 n 元联接视为星型联接。
  2. 星型联接查询中二元联接的所有联接条件必须为单列等式谓词。联接必须为内部联接。尽管可能听起来比较具有限制性,但是它涉及典型星型架构中使用代理键的事实表和维度表之间的绝大多数联接。如果联接拥有更复杂的联接条件且不符合以上所述模式,则将从星型联接排除该联接。例如,如果其中两个联接具有更复杂的联接谓词,五路联接可生成三路星型联接(其他两个联接以后再用)。
请注意,存在试探法规则。在实际情况中,很少会让试探法将维度表选作事实表。它会影响计划选择,但不会影响所选计划的正确性。然后,按选择性降序排列星型联接中的二元联接。本文中联接选择性定义为事实表的输入基数与联接的结果基数的比率 — 联接选择性表示具体维度减少了多少事实表基数。通常,我们希望首先考虑具有更高选择性的联接。
如果结果查询计划的估计查询花销适合,SQL Server 中的查询处理器会针对符合星型号联接模式和上述条件的查询自动应用优化。因此,您无需更改应用程序即可受益于这一显著的性能改进。但要注意,某些星型联接优化(如联接减少)只有 SQL Server Enterprise Edition 才提供。

星型联接性能结果
在开发 SQL Server 2008 中的星型联接优化时,我们根据基准和实际客户工作负载进行了大量性能研究。其中三种工作负载产生的结果颇具价值。
Microsoft 销售组织数据仓库 该工作负载跟踪用于 Microsoft 销售组织内部决策支持的数据仓库的性能。我们列出了一个示例快照,其中的数据库约为 750GB(包括索引)。在此工作负载中,许多查询的联接数都大于 10,因此处理起来有一定难度。
零售客户 这组试验针对零售行业中的数据仓库客户(包括常规店铺和在线展示)。客户的特点是维度建模的雪花型架构和规范的星型联接查询。我们使用约 100GB 的原始数据来填充试验用仓库快照。
决策支持工作负载 这组试验调查针对 100GB 维度建模数据库的决策支持工作负载的性能。 图 4 显示这三个工作负载的结果。该图显示了工作负载中所有查询的查询响应时间标准几何平均数。它明确指出了从工作负载运行任意查询时所期望的查询性能。图中的柱条比较了未使用星型联接优化时的基准性能 (1.0) 和星型联接优化后的性能。它们均是使用的 SQL Server 2008。
Figure 4  星型联接优化后的性能改进 (单击该图像获得较大视图)
如图所示,所有工作负载均有显著改进(12% 到 30%)。尽管具体的优势可能不尽相同,但是我们期望在 SQL Server 2008 中引入新的星型联接特定优化扩展项后,针对 SQL Server 引擎的决策支持工作负载可改善约 15%–20%。

分区表并行处理
为加快大型数据仓库的查询处理速度,数据库管理员常常按日期对大型事实表进行分区。它将数据放到不同的文件组内,从而减少了处理某一数据范围内的行时所必须搜索的数据量,并且当文件组被部署到多个物理磁盘上时,可利用底层磁盘系统的并发性能。
SQL Server 2005 可以将大型关系分成较小的逻辑块,大型表的管理因而得以改善。它还被成功用于改善查询处理,尤其是对于大型决策支持应用程序而言更显成效。
遗憾地是,某些使用 SQL Server 2005 的客户发现针对这些分区表的查询存在性能问题 — 尤其是在并行共享内存多处理器机器上运行时。在 SQL Server 2005 中针对分区表处理并行查询时,仅分配可用线程的一个子集执行查询时会出现上述情况。
试想有一台查询最多可并行使用 64 个线程的 64 核机器,并且查询会涉及两个分区。使用 SQL Server 2005 时,它仅接收 64 个线程中的 2 个,因此可能仅使用了机器 CPU 能力的 2/64(3.1%)。据报告称,对于相同的事实表,分区情况下的查询性能可能比未分区时在相同机器上运行相同查询时的性能要差 10 倍甚至更多。
需要注意的是,SQL Server 2005 针对涉及单个分区的查询进行了专门优化。此时,查询处理器会分配所有可用线程来执行扫描。这种特殊优化为在多核机器上执行的单分区查询带来了显著的性能提高,对于那些查询涉及多个分区的客户而言,他们当然也期待获得这一提高。
SQL Server 2008 引入了新的分区表并行处理 (PTP) 功能,通过更好地利用现有硬件的处理能力(而不管查询涉及多少个分区或者各个分区的相对大小如何),改进了分区情况下的查询性能。在包含分区事实表的典型数据仓库情形中,用户会发现并行计划的执行查询有了显著的改进,尤其是当可用处理器核数大于查询所涉及的分区数时。该新功能默认启用,无需任何调整或配置。
假设我们有一个分布在四个分区中的事实表,它代表按销售日期组织的销售数据。 图 5 中的图表将有助于您形象地描述该示例。请注意,这里使用的并非针对整个日期范围的单个聚集索引(就像在非分区时一样),而是为事实表中每个分区的日期列设定一个聚集索引。现在假设查询 Q 汇总最近七天的销售数据。由于新的销售数据始终通过最后一个分区(即 P4)进入事实表,因此查询很可能会涉及到不同的分区,具体视其执行时间而定。如图表第一行所示,Q1 查询仅涉及单个分区,而 Q2 查询则涉及两个分区,因为执行时相关数据分布在 P3 和 P4 分区上。
Figure 5  可用新 PTP 功能 (单击该图像获得较大视图)
现在假设有八个可用线程。在 SQL Server 2005 上执行 Q1 和 Q2 可能产生一些意外的行为。SQL Server 2005 具有一个优化功能,如果优化器知道在编译时查询仅涉及一个分区,则会将该分区当作单个非分区表,并生成一个使用所有可用线程来访问表的计划。
这样,涉及单个分区 (P3) 的 Q1 将生成由八个线程进行处理的计划(未显示)。对于涉及两个分区的 Q2,执行程序向每个分区分配一个线程,即使底层硬件还有其他可用线程。因此,Q2 仅利用了可用 CPU 能力中极小的一部分,并且很可能执行速度明显慢于 Q1。
在 SQL Server 2008 上执行 Q1 和 Q2 时,可用硬件利用率更高、性能更好并且对于行为的预测能力也更强。对于 Q1,执行程序仍分配全部八个可用线程来处理 P2 中的数据(未显示)。同时,Q2 则会产生一个并行计划,其中的执行程序将以轮叫方式将所有可用线程分配给 P3 和 P4,因而产生图中最下面一行所示的效果,其中两个分区中的每个分区各获得四个线程。CPU 得以充分利用,且 Q1 和 Q2 的性能不相仲伯。
通过该线程轮叫分配,如果处理器核数多于查询所涉及的分区数,查询的性能将更好。然而,遗憾地是,有时为分区分配线程并不象示例中这么简单。
对于多核处理器机器上的分区表, 图 6 进一步显示了从 SQL Server 2005 到 SQL Server 2008 所产生的性能改进。该图表着重指出了分区表的扫描性能。对于这个在 64 核且 RAM 为 256GB 的系统上执行的特殊测试,我们将 121GB 的单个表分成 11 个分区,每个均为 11GB。对于该图中所示的测试组,我们使用堆文件组织以及冷缓冲区和热缓冲区启动。所有查询均对数据执行简单扫描。
Figure 6  启用了新 PTP 功能的 SQL Server 的扫描性能 (单击该图像获得较大视图)
y 轴显示了响应时间(秒),x 轴表示并行度 (DOP),它模拟分配给查询的线程数。如您所见,在冷启动和热启动两种情况下,响应时间持续减少,直到 DOP 达到 22。此时,I/O 系统对于冷启动情形变为满负荷状态。其原因是本示例中使用的查询受 I/O 限制。如果是受 CPU 限制的工作负载,该限制可能不存在,或者仅在 DOP 更高时才会发生。
然而,代表热启动情形的曲线则随着 DOP 级别的增加,其响应时间仍在继续降低。对于 SQL Server 2005,在 DOP 11 附近,两条曲线都开始变平,因为在处理多个分区时,每个分区的线程数仅限于 1。
必须指出的一点是,实际上,增加 DOP 所取得的响应时间提高永远不可能是线性的。预期的行为更类似于阶跃函数 — 它反映出查询必须等待最慢的子件。因此,例如,仅向扫描再添加一个线程并不会加快查询,除非所有其他扫描也获得了能加快速度的其他线程。
对于其他各种硬件和文件配置,我们也通过其他试验测试了新的 PTP 行为。此时,在当 DOP 超过 1 线程/分区时,我们在吞吐量范围中观察到了类似行为。
最后(但同样重要),SQL Server 2008 中的新 PTP 功能还改善了查询计划的可读性,并允许深入洞察具体工作负载的执行。例如,作为 PTP 功能的一部分,在 showplan XML 中表示并行和串行计划的方式已得到改进,并且编译时和运行时执行计划中提供的分区信息也已增强。

数据压缩
随着商业智能的日益普及,企业将越来越多的数据灌入到其数据仓库中进行分析。这使得所管理的数据量呈指数级增长。在 1995 年,Winter Corporation 的第一份数据库容量调查指出,当时全球最大的系统包含的数据量是 TB。十年之后,最大的数据库扩大了近 100 倍。更令人惊讶的是数据仓库的大小每两年即增至原来的三倍。要管理如此大的数据并为数据仓库查询提供可接受的性能,难度可想而知。这些查询通常都非常复杂(涉及多个联接和累计),并要访问大量数据。工作负载中的许多查询还都受 I/O 限制。
本机数据压缩是这一问题的解决方案。SQL Server 2005 SP2 为小数和数字型数据引入了一个新的可变长度存储格式,即 vardecimal 存储格式。这一新存储格式可显著降低数据库的大小。而空间的节省又有助于在以下两方面改善受 I/O 限制查询的性能。首先,要读取的页面更少,其次,由于数据是以压缩格式存储在缓冲池中,因而提高了页面预期寿命(换句话说,它加大了在缓存中找到所请求页面的机率)。当然,由于需压缩和解压缩数据,从数据压缩获得的空间节省确实会产生一定的 CPU 开销。
SQL Server 2008 基于 vardecimal 存储格式构建,提供以下两类压缩:ROW 压缩和 PAGE 压缩。通过用可变长度存储格式存储所有固定长度的数据类型,ROW 压缩扩展了 vardecimal 存储格式。
固定长度数据类型示例包括:整数、字符和浮点数据类型。即使 SQL Server 将这些数据类型存储成可变长度格式,数据类型的语义仍保持不变(从应用程序角度看,数据类型仍为固定长度数据类型)。因此,既能从数据压缩受益,又无需对应用程序做任何更改。
PAGE 压缩将给定页面上一行或多行的列数据冗余降至最小。它使用 LZ78 (Lempel-Ziv) 算法的专有实现方法,在页面上仅存储一次冗余数据,然后从多个列对其进行引用。请注意,在使用 PAGE 压缩时,实际也包括了 ROW 压缩。
可针对表、索引或者分区表和索引的一个或多个分区启用 ROW 和 PAGE 压缩。因此,可极其灵活地选择要压缩的表、索引和分区,在空间节省和 CPU 影响之间取得巧妙的平衡。 图 7 显示了针对销售表(通过对齐索引分区)实现的这一平衡。
Figure 7  具有不同压缩设置的分区表 (单击该图像获得较大视图)
每个分区代表一个季度,其中“十月-十二月”为最后一个季度。假设头两个分区的访问频率不高,第三个分区为中等频率,最后一个分区的访问频率最高。此例中,一个可能的配置为前两个分区启用 PAGE 压缩,这样空间节省最大且对工作负载性能造成的影响最小,对第三个分区使用 ROW 压缩,最后一个分区不使用任何压缩。
可使用 Alter Table 或 Alter Index 数据定义语言 (DDL) 语句来联机或脱机启用压缩。SQL Server 还提供用于估计空间节省量的存储过程。所获得的空间节省取决于压缩对象的数据分布和架构。
许多客户数据库的测试结果均显示,大部分客户都可将其数据库的大小缩小 50–65%,并且受 I/O 限制的查询的性能得到了显著改善。然而,估计对受 CPU 限制查询的性能影响则有点棘手,具体取决于查询的复杂程度。在 SQL Server 中,仅当访问索引或表时才会发生解压缩开销。如果扫描运算符的相对 CPU 开销低于查询的整体 CPU 开销(数据仓库情形通常都是这样),您会发现对 CPU 利用率的影响少于 20-30%。

分区对齐的索引视图
在 SQL Server 2008 中,分区对齐的索引视图允许您更加有效地在关系数据仓库中创建和管理摘要汇总,并在之前无法有效使用它们的情形中使用它们。因而改进了查询性能。通常,您会有一个按日期分区的事实表。会针对该表定义索引视图(或摘要汇总)以加快查询速度。如果切换到新的表分区中,针对该分区表定义的分区对齐的索引视图的匹配分区也会相应切换,并且为自动切换。
它是优于 SQL Server 2005 的一个重大改进,在 SQL Server 2005 中,必须丢弃针对分区表定义的所有索引视图,然后才能使用 ALTER TABLE SWITCH 操作来切换入或切换出分区。SQL Server 2008 中的分区对齐索引视图功能向您提供了针对大型分区表定义的索引视图的各项好处,而不必对整个分区表重新构建汇总。这些好处包括自动维护汇总以及索引视图匹配。

分区级锁升级
SQL Server 支持范围分区,即允许针对可管理性分区数据,或根据其使用模式对数据进行分组。因此,可按月度或季度等标准对销售数据进行分区。可将分区映射到自身的文件组,再将文件组映射到一组文件。它提供了两大好处。首先,可将分区作为独立的单元进行备份和恢复。第二,可根据使用模式或查询负载将文件组映射到慢速或快速 I/O 子系统。
数据访问模式是这里非常有趣的特点。查询和 DML 操作可能仅需访问或处理分区的一个子集。举例而言,如果要分析 2004 年度的销售数据,仅需访问相关的分区,理想情况下,不应受到并发访问其他分区数据的查询的影响(系统资源除外)。在 SQL Server 2005 中,并发访问其他分区中的数据可能导致将表锁定,从而影响对其他分区的访问。
为将该干扰降至最低,SQL Server 2008 引入了表级选项来控制分区级或表级的锁升级。默认情况下,启用表级的锁升级(如 SQL Server 2005)。但,您可覆盖表的锁升级策略。例如,可按以下所示设置锁升级: