数据仓库的 RDBMS 性能优化指南(1)

http://tech.ddvip.com   2008年09月09日    社区交流

内容摘要:本性能优化指南旨在帮助数据库管理员和开发人员配置 Microsoft® SQL Server™ 2000,以获得最佳的性能,并帮助找出造成关系数据库(包括用于数据仓库的数据库)性能低下的原因。本指南还就如何装载、索引和编写查询以访问 SQL Server 中存储的数据提供了指导原则和最佳做法。另外还介绍了多种可用于分析性能特征的 SQL Server 工具。

  简介

  Microsoft SQL Server 7.0 中引入了一项重大改进:一个在很大程度上可以自行配置、自行优化和自行管理的数据库引擎。在 SQL Server 7.0 面世之前,大多数数据库服务器都会耗费数据库管理员大量的时间和精力,他们必须手动优化服务器配置以获得最佳性能。实际上,很多竞争性数据库产品现在仍要求管理员手动配置和优化他们的数据库服务器。这是许多客户改用 SQL Server 的主要原因。SQL Server 2000 是在 SQL Server 7.0 奠定的坚实基础上更上层楼的产品。SQL Server 的目标是:通过实现数据库引擎自行优化并允许 DBA 自动完成管理任务,使 DBA 不必手动配置和不断优化数据库服务器。

  尽管现在仍可以手动配置和调整一些 sp_configure 选项,但建议数据库管理员尽量不要这样做,而是让 SQL Server 自动配置和优化。对于这种调整能力,SQL Server 7.0 具有已被广泛认可且经过实践证明的成绩记录,SQL Server 2000 对此方案进行了显著的改进。环境中不断变化的条件可能会对数据库性能产生负面影响,所以,让 SQL Server 自行优化,就可以使数据库服务器进行动态调整以适应这些变化。

  性能优化的基本原则

  您可以采取许多措施来管理数据库的性能。SQL Server 2000 提供了几种工具来帮助您完成这些任务。

  管理性能

  让 SQL Server 完成大多数优化任务。

  SQL Server 2000 经过了重大改进,可以创建基本上能够进行自动配置和自行优化的数据库服务器。利用 SQL Server 自动优化设置这一优点,可帮助 SQL Server 即使在用户负荷和查询随时间不断变化的情况下也能以最高性能运行。

  管理 RAM 缓存。

  RAM 是一种有限的资源。任何数据库服务器环境的一个主要部分就是管理随机存取存储器 (RAM) 缓冲区缓存。访问 RAM 缓存中的数据比访问磁盘中同样的信息要快得多。但是,RAM 资源是有限的。如果可以将数据库 I/O(针对物理磁盘子系统的输入/输出操作)减少到最低所需的数据集和索引页,这些页将在 RAM 中停留更长时间。如果流入缓冲区缓存的不必要的数据和索引信息过多,会将有价值的页很快排挤出去。性能优化的主要目标是减少 I/O,以使缓冲区缓存得到最充分的利用。

  创建和维护合适的索引。

  对于所有的数据库查询,维护最小 I/O 的一个关键因素是确保创建和维护合适的索引。

  对大数据集和索引进行分区。

  要减少总体 I/O 争用现象并改善并行操作,请考虑对表数据和索引进行分区。本章介绍了使用 SQL Server 2000 实现和管理分区的多种方法。

  监视磁盘 I/O 子系统的性能。

  物理磁盘子系统必须为数据库服务器提供足够的 I/O 处理能力,以使数据库服务器在运行时不会出现磁盘排队现象。磁盘排队现象会导致性能不佳。本文介绍了如何检测磁盘 I/O 问题以及如何解决这些问题。

  优化应用程序和查询。

  当数据库服务器通过给定的应用程序为来自成百上千个连接的请求提供服务时,这种优化变得尤为重要。由于应用程序通常会确定要在数据库服务器上执行的 SQL 查询,所以应用程序开发人员一定要了解 SQL Server 的结构基础知识以及如何充分利用 SQL Server 的索引来最小化 I/O。

  优化活动数据。

  在许多商业智能数据库中,绝大多数数据库活动都会涉及最近一个月或一个季度的数据(多达 80% 的数据库活动都可能是因最近装载的数据而发生的)。要保持良好的数据库总体性能,在对这些数据进行装载、索引和分区时,所采取的方式一定要能够为这些数据提供最佳的数据访问性能。

  利用 SQL Server 性能工具

  SQL 事件探查器和索引优化向导

  SQL 事件探查器可用于监视和记录 SQL Server 的工作负荷。然后,可以将记录下来的工作负荷可以提交到索引优化向导,这样,在必要的时候就可以更改索引来帮助提高性能。SQL 事件探查器和索引优化向导可帮助管理员实现优化的索引。定期使用这些工具可使 SQL Server 保持良好的性能,即使查询工作负荷随时间而变化也是如此。

  SQL 查询分析器和图形执行计划

  在 SQL Server 2000 中,SQL 查询分析器提供了“图形执行计划”,使用这种方法可以方便地分析有问题的 SQL 查询。“统计 I/O”是 SQL 查询分析器的另一个重要功能,本章后面将会进行介绍。

  系统监视器对象

  SQL Server 提供了一组系统监视器对象和计数器,可以为监视和分析 SQL Server 的运行状况提供信息。本章介绍了要监视的关键计数器。

  影响性能的配置选项最大异步 IO

  SQL Server 7.0 中的手动配置选项最大异步 I/O 在 SQL Server 2000 中已经实现了自动化。以前,最大异步 I/O 用于指定在一次检查点操作过程中,SQL Server 7.0 可以向 Microsoft Windows NT® 4.0 和 Windows® 2000 同时提交的磁盘 I/O 请求的数量。Windows 接下来又将这些请求提交到物理磁盘子系统。此配置设置实现自动化后,SQL Server 2000 就能够以动态方式自动维护最佳的 I/O 吞吐量。

  注意 Windows 98 不支持异步 I/O,因此在该平台上不支持最大异步 I/O 选项。

  数据库恢复模型

  SQL Server 2000 引入了在数据库级别对事务记录方式进行配置的功能。选定的模型会对性能产生很大的影响,尤其是在数据装载过程中。恢复模型有三种:“完全”、“大容量日志记录的”和“简单”。新数据库的恢复模型是在新数据库创建时从模型数据库继承的。在创建数据库之后,可以更改它的模型。

  “完全恢复”可为将数据库恢复到以前的时间点提供最大的灵活性。

  “大容量日志记录的恢复”可为某些大规模操作(例如,创建索引或大容量复制)提供较高的性能并占用较少的日志空间。这种恢复的缺点是与时间点恢复相比不够灵活。

  “简单恢复”提供的性能最高,占用的日志空间最少,但在系统发生故障时丢失数据的风险很大。在使用“简单恢复”模型时,数据只能恢复到上次(最近一次)进行完全数据库或差异备份时的状态。在这一模型中,由于事务在日志中会从检查点处截断,因此不能使用事务日志备份来恢复事务。这会产生丢失数据的可能。在不再需要日志空间以从服务器故障(活动事务)进行恢复之后,日志空间就会被截断并重新使用。

  经验丰富的管理员可以使用这个恢复模型功能来大大加快数据装载和大容量操作的速度。不过,根据所选模型不同,丢失数据的可能性也各不相同。

  重要说明 在选择某种恢复模型之前,必须仔细考虑会遇到的风险。

  每种恢复模型致力于满足不同的需要。请根据所选的模型权衡利弊。权衡的结果需对性能、空间利用率(磁盘或磁带)和防范数据丢失的保护措施等方面加以综合考虑。当您选择恢复模型时,需要结合以下几个方面的业务需求作出决定:

  大规模操作(例如,创建索引或大容量装载)的性能

  数据丢失的可能性(例如,丢失已提交的事务)

  事务日志空间占用大小

  备份和恢复过程的难易

  根据所执行的操作不同,一种模型可能会比另一种模型更适合。在选择一种恢复模型之前,请考虑它将带来的影响。下表提供了一些帮助性信息。

恢复模型优点丢失所做工作的可能性是否恢复到时间点?
简单可高性能地完成大容量复制操作。

  可回收日志空间,使空间要求保持较低的水平。

自最近的数据库备份或差异备份以来所做的更改必须重做可以恢复到任何备份的结束点。此后的更改必须重做。
完全不会因数据文件丢失或损坏而丢失所做的工作。

  可恢复到任意时间点(例如,发生应用程序或用户错误之前的那一刻)。

通常没有风险。

  如果日志受到损坏,则必须重做自最近的日志备份以来所做的更改。

可恢复到任意时间点。
大容量日志记录的可高性能地完成大容量复制操作。

  大容量操作使用最小的日志空间。

如果日志受到损坏,或者自最近的日志备份以来出现过大容量操作,则必须重做自上次备份以来所做的更改。

  除此之外,不会丢失所做的任何工作。

可以恢复到任何备份的结束点。此后所做的更改必须重做。

  有关多实例的注意事项

  SQL Server 2000 中还引入了在一台计算机上运行 SQL Server 的多个实例的功能。默认情况下,SQL Server 的每个实例会动态地获取和释放内存,以针对实例的工作负荷的变化进行调整。当 SQL Server 2000 有多个实例,而每个实例都独立地自动调整内存使用量时,性能优化会变得很复杂。大多数高端的业务智能客户通常只在每台计算机上安装一个 SQL Server 实例,因此对于他们来说,通常不需要考虑这项功能。但是,随着计算机个体变得越来越大(Windows 2000 Datacenter Server 最多支持 64 GB RAM 和 32 个 CPU),在有些生产环境中,可能会出现对多个实例的需求。那些利用扩展内存支持的实例需要特别关注。

  扩展内存支持

  一般情况下,SQL Server 2000 会根据需要动态地获取和释放内存,所以管理员通常不需要指定应该为 SQL Server 分配多少内存。但是,SQL Server 2000 企业版和 SQL Server 2000 开发人员版引入了对使用 Microsoft Windows 2000 Address Windowing Extensions (AWE) 的支持。这样,SQL Server 2000 就可以对更多的内存进行寻址(对于 Windows 2000 Advanced Server 最多约 8 GB;对于 Windows 2000 Datacenter Server 最多约 64 GB)。在配置了扩展内存的情况下,必须将访问扩展内存的每个实例配置为静态分配它将使用的内存。

  注意 只有当您运行 Windows 2000 Advanced Server 或 Windows 2000 Datacenter Server 时,才可使用这项功能。

  使用 Windows 2000 的注意事项

  要利用 AWE 内存,必须使用已分配了 Windows 2000 的“内存中锁定页”特权的 Windows 2000 帐户运行 SQL Server 2000 数据库引擎。SQL Server 安装程序将自动授权 MSSQLServer 服务帐户使用内存中锁定页选项。如果您从命令提示符使用 Sqlservr.exe 来启动 SQL Server 2000 的实例,必须使用 Windows 2000 的“组策略”实用工具 (Gpedit.msc) 将这一权限手动分配给交互操作的用户帐户,否则的话,如果 SQL Server 不作为服务运行就将无法使用 AWE 内存。

  启用“内存中锁定页”选项

  在开始菜单上,单击运行,然后在打开框中输入 gpedit.msc。

  在组策略树窗格中,展开计算机配置,然后展开 Windows 设置。

  展开安全性设置,然后展开本地策略。

  选择用户权限分配文件夹。

  策略将会显示在详细信息窗格中。

  在详细信息窗格中,双击内存中锁定页。

  在本地安全性策略设置对话框中,单击添加。

  在选择用户或组对话框中,添加一个有权运行 Sqlservr.exe 的帐户。

  要使 Windows 2000 Advanced Server 或 Windows 2000 Datacenter Server 能够支持 4 GB 以上的物理内存,必须将 /pae 参数添加到 Boot.ini 文件中。

  对于内存不超过 16 GB 的计算机,您可以在 Boot.ini 文件中使用 /3gb 参数。这就使 Windows 2000 Advanced Server 和 Windows 2000 Datacenter Server 能够允许用户应用程序通过 3 GB 的虚拟内存来对扩展内存进行寻址,并且为操作系统本身保留 1 GB 虚拟内存。

  如果计算机上的物理内存超过 16 GB,则 Windows 2000 操作系统本身会需要 2 GB 虚拟内存地址空间用于系统开销。因此,它只能支持将 2 GB 虚拟地址空间用于应用程序开销。对于物理内存超过 16 GB 的系统,一定要在 Boot.ini 文件中使用 /2gb 参数。

  注意 如果您意外使用了 /3gb 参数,Windows 2000 将无法对 16 GB 以上的任何内存进行寻址。

  使用 SQL Server 2000 的注意事项

  要使 SQL Server 2000 的实例能够使用 AWE 内存,请使用 sp_configure 来设置启用 awe 选项。然后,重新启动 SQL Server 以激活 AWE。由于 AWE 支持会在 SQL Server 启动过程中启用,并在 SQL Server 关闭前一直保持启用状态,所以,在 AWE 处于使用状态时,SQL Server 会通过向 SQL Server 错误日志发送“已启用 Address Windowing Extension”消息来通知用户。

  当您启用 AWE 内存时,SQL Server 2000 的实例不会动态管理地址空间的大小。因此,当您启用 AWE 内存并启动 SQL Server 2000 的实例时,根据最大服务器内存的设置方式不同,会出现下列情况之一。

  如果已经设置了最大服务器内存并且计算机上至少有 3 GB 可用内存,则该实例获取在最大服务器内存中指定的内存量。如果计算机上可用的内存量小于最大服务器内存(但是大于 3 GB),则该实例获取几乎所有的可用内存,并且可能最多只留下 128 MB 可用内存。

  如果尚未设置最大服务器内存并且计算机上至少有 3 GB 可用内存,则该实例几乎获取所有的可用内存,并且可能最多只留下 128 MB 可用内存。

  如果计算机上的可用内存不足 3 GB 而且内存是动态分配的,则无论为启用 awe 设置了什么参数,SQL Server 都将以非 AWE 模式运行。

  当在 32 GB 系统上分配 SQL Server AWE 内存时,Windows 2000 可能至少需要 1 GB 可用内存来管理 AWE。因此,如果在启动 SQL Server 的实例时已启用了 AWE,建议您不要使用默认的最大服务器内存设置,而应将它限制在 31 GB 或更小。

  有关故障转移群集和多实例的注意事项

  如果您在使用 AWE 内存的同时使用 SQL Server 2000 故障转移群集或者运行多个实例,则必须确保正在运行的所有 SQL Server 实例的最大服务器内存设置的值的总和小于可用的物理 RAM 量。对于故障转移,您必须考虑任何候选存活节点上物理 RAM 的最小量。如果故障转移节点上的物理内存比初始节点上的少,则 SQL Server 2000 的实例可能无法启动或者启动时用的内存比其在初始节点上的少。

  sp_configure 选项

  “并行度的成本阈值”选项

  使用并行度的成本阈值选项可指定 SQL Server 创建和执行并行计划所用的阈值。只有当为同一个查询执行串行计划的预计成本高于在并行度的成本阈值中设置的值时,SQL Server 才为查询创建和执行并行计划。成本是指对特定的硬件配置执行串行计划时预计需要的时间(以秒为单位)。只针对对称多处理器 (SMP) 设置并行度的成本阈值。

  通常,并行计划对较长的查询有利;性能上的优势可以补偿初始化、同步以及终止计划所需的额外时间。在混合执行短查询和长查询时,通常会使用并行度的成本阈值选项。短查询执行串行计划,而长查询使用并行计划。并行度的成本阈值的值决定哪些查询被视为短查询,从而只执行串行计划。

  在有些情况下,即使查询的成本计划小于当前的并行度的成本阈值值,也可以选择并行计划。这是因为就并行度的成本阈值而言,使用并行计划还是串行计划要根据完全优化完成之前提供的预计成本来决定。

  并行度的成本阈值选项可以设置为从 0 到 32767 的任何值。默认值是 5(以毫秒为单位)。如果计算机只有一个处理器,或者如果由于关系掩码配置选项的值而使得 SQL Server 只能使用一个 CPU,或者如果最大并行度选项设置为 1,那么,SQL Server 会忽略并行度的成本阈值。

  “最大并行度”选项

  最大并行度选项用于限制在执行并行计划时使用的处理器数(最多 32 个)。默认值是 0,此时使用可用的实际数量的 CPU。将最大并行度选项设置为 1 可强制取消生成并行计划。如果将该值设置为大于 1 的数字,则可以限制在执行单个查询时使用的最大处理器数。如果将该值指定为大于可用 CPU 数量的数字,则使用可用的实际数量的 CPU。

  注意 如果未将关系掩码选项设成默认值,则在对称多处理器 (SMP) 系统上可供 SQL Server 使用的 CPU 数可能会受到限制。

  对于在 SMP 计算机上运行的服务器,很少改变最大并行度。如果计算机只有一个处理器,则会忽略最大并行度值。

  “优先级提升”选项

  优先级提升选项用于指定 SQL Server 是否应当以高于同一台计算机上其他进程的调度优先级运行。如果将该选项设置为 1,SQL Server 将在 Windows 调度程序中按照 13 的优先级基数运行。默认值是 0,表示优先级基数 7。优先级提升选项只应当用在 SQL Server 专用且具有 SMP 配置的计算机上。

  注意 如果将优先级提升得太高,则可能会使基本操作系统和网络功能的资源不足,从而造成关闭 SQL Server 或使用服务器上的其他 Windows 任务等问题。

  在某些情况下,如果将优先级提升设置为默认值以外的任何值,可能会导致在 SQL Server 错误日志中记录以下通讯错误:

Error: 17824, Severity: 10, State: 0 Unable to write to ListenOn
connection '<servername>', loginname '<login ID>', hostname '<hostname>'
OS Error: 64, The specified network name is no longer available.

  错误 17824 指出在尝试写入客户端时 SQL Server 遇到连接问题。如果客户端已停止响应,或者客户端已经重新启动,则这些通讯问题可能是由网络问题引起的。但是,错误 17824 不一定表示网络问题,而可能只是设置优先级提升选项的结果。

  “设置工作集大小”选项

  设置工作集大小选项用于为 SQL Server 保留等于服务器内存设置的物理内存空间。服务器内存设置由 SQL Server 根据工作负荷和可用资源自动配置。它将在最小服务器内存和最大服务器内存之间显著变化。设置设置工作集大小的意思是:即使在 SQL Server 空闲时,另一个进程可以更容易地使用 SQL Server 页,操作系统也不尝试换出这些页。

  如果您要允许 SQL Server 动态使用内存,请不要设置设置工作集大小。在将设置工作集大小设置为 1 之前,请将最小服务器内存和最大服务器内存设置为同一个值(希望 SQL Server 使用的内存量)。

  轻量池和关系掩码选项将在本章后面的“要监视的关键性能计数器”一节讨论。

  优化磁盘 I/O 性能

  如果您配置的 SQL Server 将只包含几 GB 数据,而且不负担繁重的读写活动,可以不必考虑磁盘 I/O 以及通过平衡硬盘驱动器间的 SQL Server I/O 活动来实现最大性能等事项。但是,要创建大型 SQL Server 数据库来包含数百 GB 甚至 TB 的数据,并且/或者要能够负担繁重的读/写活动,则有必要进行相应的配置,以平衡多个硬盘驱动器间的负载,从而最大程度地提高 SQL Server 的磁盘 I/O 性能。

  优化传输速度

  对于数据库性能优化来说,最重要的方面之一就是优化 I/O 性能。当然,SQL Server 也不例外。除非运行 SQL Server 的计算机有足够的 RAM 来容纳整个数据库,否则 I/O 性能将由磁盘 I/O 子系统处理 SQL Server 读写数据的速度来确定。

  因为传输速度、I/O 吞吐量和可能影响 I/O 性能的其他因素不断改善,所以我们将不针对应当从存储系统中期望看到哪种速度给出具体数字。为了更好地理解可期望获得的性能,建议您与首选的硬件供应商协作确定期望的最优性能。

  我们必须要强调的是顺序 I/O 操作(通常又称为“序列”或“按磁盘顺序”)与非顺序 I/O 操作之间的差异。我们还希望大家注意预读可能对 I/O 操作产生的显著影响。

  顺序和非顺序磁盘 I/O 操作

  有必要解释以下这些术语相对于磁盘驱动器的含义。通常,一个硬盘驱动器由一组驱动器盘片组成。每个盘片都提供用于读取/写入操作的表面。一组带有读取/写入磁头的臂用于在这些盘片之间移动,并且从盘片的表面读取数据或者向其中写入数据。就 SQL Server 而言,有关硬盘驱动器的以下两点很重要,需要记住。

  第一,读取/写入磁头和相关的磁盘臂需要移动,以定位到 SQL Server 请求的硬盘驱动器盘片上的位置并针对其进行操作。如果数据不按位置顺序分布到硬盘驱动器盘片上,则硬盘驱动器需要花更多的时间来移动磁盘臂(寻道时间)和旋转读/写头(旋转滞后时间)来找到数据。这与按位置顺序分布时的情形完全不同,在该情况下,所需的全部数据都位于硬盘驱动器盘片的一个连续物理扇区上,因此磁盘臂和读取/写入磁头在执行所需的磁盘 I/O 时移动量很少。

  非顺序和顺序情形的时间相差很大:每次非顺序寻道大约花费 50 毫秒,而顺序寻道则大约需要两三毫秒。请注意,这些时间是大致估计值,并且将根据以下因素而有所变化:非顺序数据在磁盘上的分布距离、硬盘盘片可以旋转的速度 (RPM) 以及硬盘驱动器的其他物理属性。主要的一点是顺序 I/O 有助于提高性能,而非顺序 I/O 会降低性能。

  第二,一定要记住,读写 8 KB 与读写 64 KB 所需的时间几乎一样多。在 8 KB 到大约 64 KB 的范围内,磁盘臂以及读/写头的移动(寻道时间和旋转滞后时间)仍然占一次磁盘 I/O 传输操作所需时间的大部分。因此,从数学角度讲,在需要传输 64 KB 以上的 SQL Server 数据时,因为 64 KB 与 8 KB 的传输速度基本上一样,但每次传输所处理的 SQL Server 数据却是后者的 8 倍,所以最好尝试尽可能多地执行 64 KB 磁盘传输操作。请记住,预读管理器在 64 KB 区块(称作 SQL Server 扩展盘区)中执行它的磁盘操作。日志管理器也以较大的 I/O 大小执行顺序写入。要记住的主要一点是,如果充分利用预读管理器并将 SQL Server 日志文件与不按顺序访问的其他文件分开,会改善 SQL Server 性能。

  根据经验,大多数硬盘驱动器处理顺序 I/O 操作时所提供的性能是处理非顺序 I/O 操作时的 2 倍。即,需要非顺序 I/O 的操作所花费的时间是执行顺序 I/O 操作的两倍。因此,要尽可能避免可能导致数据库中出现随机 I/O 的情况。虽然应当尽量按顺序执行 I/O 操作,但是像页拆分或者数据无序这样的情形还是可能会导致出现非顺序 I/O。

  为了促使执行顺序 I/O,一定要避免出现导致页拆分的情形。设计一个精心安排的数据装载策略也会有所帮助。您可以通过利用可分隔数据和索引的分区策略来促使在磁盘上按顺序分布数据。一定要设置作业以定期检查数据和索引中是否有碎片,并且在数据碎片太多时,使用 SQL Server 随付的实用工具来对数据重新排序。有关执行这些操作的更多信息将在本章的稍后部分介绍。

  注意 因为事务日志数据总是以不超过 32 KB 的大小按顺序写入日志文件中,所以日志通常不是主要的考虑事项。

  RAID

  RAID(廉价磁盘冗余阵列)是一种存储技术,通常用于大于几 GB 的数据库。RAID 既具有性能优点又具有容错优点。多个 RAID 控制器和磁盘配置会在成本、性能和容错之间提供平衡。本主题简单介绍了将 RAID 技术用于 SQL Server 数据库的情况,并讨论了各种配置以及平衡方案。

  性能。硬件 RAID 控制器将从 Windows NT 4.0 与 Windows 2000 和应用程序(例如 SQL Server)中读取/写入的所有数据划分为很多切片(通常是 16–128 KB),这些切片随后会分布到所有参与 RAID 阵列的磁盘上。按这种方式将数据拆散到各个物理驱动器上会有这样的效果:读取/写入 I/O 工作负荷会平均分布到所有参与 RAID 阵列的物理硬盘驱动器上。这样就会提高磁盘 I/O 性能,因为参与 RAID 阵列的硬盘在总体上保持相同程度的闲忙,而不会因 I/O 请求分布不均而导致某些磁盘成为瓶颈。

  容错。 RAID 还通过使用镜像和奇偶校验这两种方法来防止硬盘出现故障并因此造成数据丢失。

  镜像通过将信息写入另一组(镜像)驱动器上来实现。如果在有镜像时丢失了驱动器,则可以通过更换有故障的驱动器并重建镜像集来重建丢失驱动器上的数据。大多数 RAID 控制器都会提供在 Windows NT 4.0 和 Windows 2000 以及 SQL Server 联机的情况下更换故障驱动器并重新镜像的功能。这样的 RAID 系统通常被称作能够“热插拔”的驱动器。

  镜像有一个优点:如果需要容错,它所实现的性能是 RAID 选项中最佳的。请切记,SQL Server 每次写入镜像集时,都会执行两个磁盘 I/O 操作,对于镜像集的每一面各执行一个这样的操作。另一个优点是:进行镜像比实现奇偶校验 RAID 提供的容错更多。镜像能够使系统在至少一个驱动器发生故障后继续运行,而且,在镜像集中多达半数的驱动器都有故障的情况下,也许还能够支持系统,而不是强制系统管理员关闭服务器并从文件备份中恢复。

  镜像的缺点是成本高。镜像的磁盘成本是:每个需要用来存放数据的驱动器都额外需要一个驱动器。这实际上就会使存储成本增加一倍,对于数据仓库来说,存储器通常是所需的最昂贵的组件之一。RAID 1 及其混合 RAID 0+1(有时称作 RAID 10 或 0/1)都是通过镜像实现的。

  奇偶校验是这样实现的:计算有关写入磁盘的数据的恢复信息,然后将该奇偶校验信息写入构成 RAID 阵列的其他驱动器。如果某个驱动器发生故障,一个新驱动器就会插入 RAID 阵列,并通过提取写入其他驱动器上的恢复信息(奇偶校验),使用这些信息重新生成故障驱动器上的数据,从而恢复故障驱动器上的数据。RAID 5 及其混合通过奇偶校验实现。

  奇偶校验的优点是成本低。要用 RAID 5 保护任意数量的驱动器,只需要另外增加一个驱动器。奇偶校验信息会均匀分布在参与 RAID 5 阵列的所有驱动器上。奇偶校验的缺点是性能和容错能力。由于在计算和写入奇偶校验时会额外带来成本,因此 RAID 5 对于每次写入都需要四个磁盘 I/O 操作,而镜像只需两个磁盘 I/O 操作。镜像和奇偶校验的读取 I/O 操作成本是相同的。但是,读取操作通常会发生在有故障的驱动器上,此后,必须将阵列脱机,而且必须从备份介质中执行恢复,以恢复数据。

  一般经验:一定要在所需的任意多个磁盘上进行条带化,以实现可靠的磁盘 I/O 性能。系统监视器将会指出在特定的 RAID 阵列上是否存在磁盘 I/O 瓶颈。请准备根据需要添加磁盘,并将数据重新分布到 RAID 阵列和/或小型计算机系统接口 (SCSI) 通道中,以平衡磁盘 I/O 并最大限度地提高性能。

  硬件 RAID 控制器板载缓存的效果

  许多硬件 RAID 控制器都有某种形式的读取和/或写入缓存。对 SQL Server 来说,这种可用的缓存功能可以显著增强磁盘子系统高效处理 I/O 的能力。这些基于控制器的缓存机制的原理是:收集来自主机服务器 (SQL Server) 的较小的并且有可能是非顺序的 I/O 请求,然后尝试在几毫秒内将它们与其他 I/O 请求合成一批,这样,成批的 I/O 就可以形成较大 (32–128 KB) 并且有可能是顺序 I/O 请求,以便发送到硬盘驱动器。

  按顺序的和较大的 I/O 请求有利于提高性能,请遵循这一原则,因为在硬盘驱动器能够向 RAID 控制器提供固定数量 I/O 的情况下,这样有助于产生更大的磁盘 I/O 吞吐量。硬盘每秒能够处理更多的 I/O,并不是 RAID 控制器的缓存功能有多么神奇,而是因为 RAID 控制器缓存使用了某种组织方式来排列传入的 I/O 请求,从而能够尽可能充分地利用好基础硬盘固定的 I/O 处理能力。

  这些 RAID 控制器通常用某种形式的后备电源来保护它们的缓存机制。这种后备电源可以帮助在断电时,将写入缓存中的数据保留一段时间(可能是几天)。如果数据库服务器也由不间断电源 (UPS) 支持,在断电时,RAID 控制器会有更多的时间和机会将数据刷新到磁盘中。虽然服务器的 UPS 不直接影响性能,但它的确可以为 RAID 控制器缓存所提供的性能改进提供保护。

  RAID 级别

  如上所述,在 RAID 的各个级别中,RAID 1 和 RAID 0+1 提供最佳的数据保护和最佳性能,但是就所需的磁盘而言会需要更多的成本。当硬盘成本不是限制因素时,就兼顾性能和容错而言,RAID 1 或 RAID 0+1 是最佳选择。

  RAID 5 的成本比 RAID 1 或 RAID 0+1 低,但是它提供的容错和写入性能较差。RAID 5 的写入性能大约只是 RAID 1 或 RAID 0+1 的一半,这是因为 RAID 5 读取和写入奇偶校验信息需要额外的 I/O。

  使用 RAID 0 可实现最佳磁盘 I/O 性能(磁盘条带化没有容错保护)。因为 RAID 0 不提供容错保护,所以决不应当将它用在生产环境中,也不建议将它用在开发环境中。RAID 0 通常只用于基准检验或测试。

  许多 RAID 阵列控制器都通过物理硬盘驱动器提供 RAID 0+1(又称作 RAID 1/0 和 RAID 10)选项。RAID 0+1 是一种混合 RAID 解决方案。在较低级别,该控制器像普通的 RAID 1 那样镜像所有的数据。在较高级别,它(像 RAID 0 一样)将数据条带化到所有的驱动器上。因此,RAID 0+1 提供最大的保护(镜像)和高性能(条带化)。因为这些条带化和镜像操作由 RAID 控制器进行管理,所以它们对于 Windows 和 SQL Server 是透明的。RAID 1 和 RAID 0+1 之间的区别在硬件控制器级别上。对于给定的存储量,RAID 1 和 RAID 0+1 需要相同数量的驱动器。有关以 RAID 0+1 方式实现特定 RAID 控制器的更多信息,请与生产该控制器的硬件供应商联系。

  下面的插图显示了 RAID 0、RAID 1、RAID 5 和 RAID 0+1 之间的区别。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  注意 在上面的插图中,为了容纳相当于四个磁盘的数据,RAID 1(和 RAID 0+1)需要八个磁盘,而 Raid 5 只需要五个磁盘。一定要咨询您的存储器供应商,以了解有关他们特定的 RAID 实现的更多信息。

  0 级

  因为该级别使用名为条带集的磁盘文件系统,所以又将它称作磁盘条带。数据被划分成多个块并按固定顺序分布到阵列中的所有磁盘上。RAID 0 将多个操作分布到多个磁盘上,以便可以同时独立地执行这些操作,从而改善了读取/写入性能。RAID 0 类似于 RAID 5,但是 RAID 5 还提供容错功能。

  下面的插图显示的是 RAID 0。

数据仓库的 RDBMS 性能优化指南(1)

  1 级

  因为该级别使用名为镜像集的磁盘文件系统,所以又将它称作磁盘镜像。磁盘镜像可提供一个与所选磁盘完全相同的冗余副本。写入主磁盘的所有数据都会写入镜像磁盘。RAID 1 提供了容错功能,而且通常可以改进读取性能(但是可能会降低写入性能)。下面的插图显示的是 RAID 1。

数据仓库的 RDBMS 性能优化指南(1)

  2 级

  该级别通过使用将奇偶校验分布到所有磁盘上的纠错方法来添加冗余。它还利用磁盘条带策略将一个文件分成多个字节并将该文件分布到多个磁盘上。与镜像 (RAID 1) 相比,该策略在磁盘利用率和读取/写入性能方面只带来了很小的改进。RAID 2 不如其他 RAID 级别效率高,通常不使用它。

  3 级

  该级别使用与 RAID 2 相同的条带化方法,但是纠错方法只需一个磁盘用于奇偶校验数据。磁盘空间的使用情况因数据磁盘的数量而异。RAID 3 在读取/写入性能方面提供一些改进。RAID 3 也极少使用。

  4 级

  该级别使用的条带数据块或段比 RAID 2 或 RAID 3 大得多。与 RAID 3 一样,纠错方法只需一个磁盘用于奇偶校验数据。它将用户数据与纠错数据分开。RAID 4 不如其他 RAID 级别效率高,通常不使用。

  5 级

  该级别又称作具有奇偶校验的条带化,它是新设计中最常用的策略。与 RAID 4 相似,它将数据以大块形式条带化到阵列中的磁盘上。不同之处在于它在所有磁盘之间写入奇偶校验的方式。数据冗余通过奇偶校验信息提供。数据和奇偶校验信息会在磁盘阵列上排列,所以这两种信息总是位于不同的磁盘上。与磁盘镜像 (RAID 1) 相比,具有奇偶校验的条带化可提供更好的性能。但是,当条带成员丢失时(例如,当磁盘发生故障时),读取性能会下降。RAID 5 是最常用的 RAID 配置之一。下面的插图显示的是 RAID 5。

数据仓库的 RDBMS 性能优化指南(1)

  Level 10 (1+0)

  该级别又称作具有条带化的镜像。该级别使用条带化的磁盘阵列,而该阵列又镜像到另一组相同的条带化磁盘。例如,可使用四个磁盘创建一个条带化的阵列。然后,条带化的磁盘阵列使用另一组(四个)条带化的磁盘进行镜像。RAID 10 提供磁盘条带化带来的性能益处以及镜像带来的磁盘冗余。在所有的 RAID 级别中,RAID 10 提供的读取/写入性能最高,代价是使用的磁盘数量是其他级别的两倍。下面的插图显示的是 RAID 10。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  联机 RAID 扩展

  使用该功能可以在 SQL Server 保持联机的情况下动态地给物理 RAID 阵列添加磁盘。增加的磁盘驱动器会自动集成到 RAID 存储器中。添加磁盘驱动器的方法是:将它们安装到被称为热插拔驱动器插槽或热插拔插槽的物理位置。许多硬件供应商都提供了能够实现该功能的硬件 RAID 控制器。数据会均匀地在所有驱动器(包括新添加的驱动器)之间均匀地重新进行条带化,而且不需要关闭 SQL Server 或 Windows。

  您可以通过在磁盘阵列盒中的热插拔插槽中保留空位来利用该功能。如果 SQL Server 经常因 I/O 请求而使 RAID 阵列负担过重(这可以由与该 RAID 阵列相关联的 Windows 逻辑驱动器盘符的磁盘队列长度来指示),则可能需要在 SQL Server 仍在运行时,将一个或多个新的硬盘驱动器安装到热插拔插槽中。RAID 控制器会将一些现有的 SQL Server 数据移到这些新驱动器上,以便数据均匀地分布到 RAID 阵列中的所有驱动器上。然后,新驱动器的 I/O 处理能力(每个驱动器每秒 75 个非顺序/150 个顺序 I/O)会添加到 RAID 阵列的总体 I/O 处理能力中。

  系统监视器和 RAID

  在系统监视器(在 Microsoft Windows NT® 4.0 中为性能监视器)中,可以获取逻辑磁盘驱动器和物理磁盘驱动器的信息。逻辑磁盘和物理磁盘的区别在于,在系统监视器中,逻辑磁盘与 Windows 读作逻辑驱动器盘符的内容相关联,物理磁盘与 Windows 读作一个物理硬盘的内容相关联。

  在 Windows NT 4.0 中,默认情况下,性能监视器的所有磁盘计数器都是处于关闭状态的,因为它们可能会对性能略有影响。在 Windows 2000 中,默认情况下,物理磁盘计数器处于打开状态,逻辑磁盘计数器处于关闭状态。Diskperf.exe 是一个 Windows 命令,它控制可在系统监视器中查看的计数器的类型。

  在 Windows 2000 中,要获取逻辑驱动器或存储卷的性能计数器数据,您必须在命令提示符下键入 diskperf -yv,然后按 Enter 键。这会导致用于收集磁盘性能数据的磁盘性能统计驱动程序报告逻辑驱动器或存储卷的数据。在默认情况下,操作系统使用 diskperf -yd 命令来获取物理驱动器的数据。

  在 Windows 2000 中,Diskperf.exe 的语法如下所示:

  diskperf [-y[d|v] | -n[d|v]] [computername]

  参数

  (none)

  报告磁盘性能计数器是否处于启用状态并标识启用的计数器。

  -y

  将系统设置为在计算机重新启动时启动所有的磁盘性能计数器。

  -yd

  在计算机重新启动时启用物理驱动器的磁盘性能计数器。

  -yv

  在计算机重新启动时启用逻辑驱动器或存储卷的磁盘性能计数器。

  -n

  将系统设置为在计算机重新启动时禁用所有的磁盘性能计数器。

  -nd

  禁用物理驱动器的磁盘性能计数器。

  -nv

  禁用逻辑驱动器的磁盘性能计数器。

  computername

  指定要查看或设置要使用的磁盘性能计数器的计算机。

  在 Windows NT 4.0 和更低版本中,diskperf –y 用于监视不使用 Windows NT 软件 RAID 的硬盘驱动器或者硬盘驱动器与 RAID 控制器的集和。在使用 Windows 软件 RAID 时,请使用 diskperf –ye,以便系统监视器将在 Windows NT 条带集之间正确地报告物理计数器。当结合使用 diskperf –ye 和 Windows NT 条带集时,逻辑计数器所报告的信息将不正确并且应当被忽略。如果必须将逻辑磁盘计数器信息与 Windows NT 条带集结合使用,请使用 diskperf –y。

  在使用 diskperf –y 时,逻辑磁盘计数器会被正确地报告给 Windows NT 条带集,但是物理磁盘计数器所报告的信息将不正确并且应当被忽略。

  注意 diskperf 命令要在重新启动了 Windows 之后才会起作用(Windows 2000 和 Windows NT 4.0 及更低版本均是如此)。

  有关监视硬件 RAID 的注意事项

  因为 RAID 控制器将多个物理硬盘驱动器作为一个 RAID 镜像集或条带集提供给 Windows,所以 Windows 就会像读取一个物理磁盘那样读取该分组。实际底层硬盘驱动器活动的最终抽象视图会导致性能计数器报告可能会起误导作用的信息。

  从优化性能的角度看,知道一个 RAID 阵列关联了多少物理硬盘驱动器是很重要的。在确定 Windows 和 SQL Server 发送给每个物理硬盘驱动器的磁盘 I/O 请求数时,将需要此信息。将系统监视器报告为与某个硬盘驱动器相关联的磁盘 I/O 请求数除以该 RAID 阵列中已知的实际物理硬盘驱动器数。

  要粗略估计 RAID 阵列中每个硬盘驱动器的 I/O 活动,一定还要将系统监视器报告的磁盘写入 I/O 数乘以 2(RAID 1 和 0+1)或 4 (RAID 5)。这将更精确地给出发送到物理硬盘驱动器的实际 I/O 请求数,因为正是在这个物理级别应用硬盘驱动器的 I/O 能力。但是,当硬盘 RAID 控制器使用缓存功能时,此方法无法精确计算硬盘驱动器 I/O,因为缓存功能会极大地影响对硬盘驱动器进行的直接 I/O。

  在监视磁盘活动时,最好将重点关注磁盘队列,而不是每个磁盘的实际 I/O。磁盘 I/O 的速度取决于驱动器的传输速率,而这种速率是无法调整的。除了购买更快或更多的驱动器外,您没有什么其他措施,所以,关心实际发生的 I/O 量没有什么意义。但是,您又希望避免出现过多的磁盘队列。大量的磁盘队列表明您的 I/O 有问题。因为 Windows 不能读取 RAID 阵列中物理驱动器的数量,所以很难精确估计每个物理磁盘的磁盘队列。通过将磁盘队列长度除以参与所观察的逻辑驱动器的硬件 RAID 磁盘阵列的物理驱动器数,可以确定大致的近似值。对于 SQL Server 文件所在的硬盘驱动器,努力使磁盘队列数少于两个,是最理想的。

  软件 RAID

  Windows 2000 支持软件 RAID,在不使用硬件 RAID 控制器时,软件 RAID 通过操作系统来提供镜像集和条带集(具有或不具有容错功能),从而提供容错功能。您可以使用操作系统过程来设置 RAID 0、RAID 1 或 RAID 5 功能。多数大型数据仓库都使用硬件 RAID,但是,如果您的安装规模相对较小,或者您选择不实现硬件 RAID,那么,软件 RAID 可以带来一些数据访问和容错方面的优点。

  软件 RAID 确实会占用一些 CPU 资源,因为 Windows 必须管理通常由硬件 RAID 控制器为您管理的 RAID 操作。因此,在磁盘驱动器数相同的情况下,Windows 软件 RAID 提供的性能会比硬件 RAID 低几个百分点,尤其是当系统处理器的使用率因其他目的而接近 100% 时。通过降低 I/O 瓶颈的可能性,与没有软件 RAID 时相比,Windows 软件 RAID 通常将帮助一组驱动器为 SQL Server I/O 提供更好的服务。如果使用软件 RAID,SQL Server 应该能够更好地利用 CPU,因为服务器通常等待 I/O 请求完成的时间会减少。

  磁盘 I/O 并行度

  为了改善存储在多个磁盘驱动器上的大型 SQL Server 数据库的性能,一个有效的方法是创建磁盘 I/O 并行机制,该机制同时对多个磁盘驱动器进行读写操作。RAID 通过硬件和软件实现磁盘 I/O 并行度。下一个主题讨论使用分区来组织 SQL Server 数据以进一步增加磁盘 I/O 并行度。

  使用分区来提高性能

  对于存储在多个磁盘驱动器上的 SQL Server 数据库,可通过对数据进行分区以增加磁盘 I/O 并行度来改善性能。

  可使用多种方法来进行分区。分区的创建和管理方法包括配置存储子系统(磁盘、RAID 分区)和在 SQL Server 中应用各种数据配置机制(例如,文件、文件组、表和视图)。虽然本节重点介绍一些与性能相关的分区功能,但是第 18 章“在 SQL Server 2000 数据仓库中使用分区”也特别介绍了分区主题。

  创建磁盘 I/O 并行度的最简单方法是,使用硬件分区并创建一个为所有的 SQL Server 数据库文件(事务日志文件除外,它们总是应当存储在从物理上分开且仅专用于日志文件的磁盘驱动器上)提供服务的驱动器池。驱动器池可以是一个 RAID 阵列,它在 Windows 中呈现为一个物理驱动器。可以使用多个 RAID 阵列和 SQL Server 文件/文件组来设置较大的池。可以将一个 SQL Server 文件与每个 RAID 阵列相关联,并将这些文件组合成一个 SQL Server 文件组。然后,可基于该文件组构建一个数据库,以便将数据均匀地分布到所有的驱动器和 RAID 控制器上。驱动器池方法依赖 RAID 在所有的物理驱动器之间划分数据,这样有助于确保在数据库服务器操作过程中对该数据进行并行访问。

  该驱动器池方法简化了 SQL Server I/O 的性能优化,因为数据库管理员知道只有一个物理位置可供创建数据库对象。可监视单个驱动器池的磁盘队列情况,必要时可向该池中添加更多的硬盘驱动器以防出现磁盘排队现象。一般情况下,无法确定数据库哪些部分的利用率最高,此时使用该方法有助于优化性能。最好不要只是因为 SQL Server 可能要用 5% 的时间来对另一磁盘分区进行 I/O 而将总体可用 I/O 能力的一部分隔离到该磁盘分区上。“单个驱动器池”方法有助于使所有可用的 I/O 能力对于 SQL Server 操作“始终”可用。它还允许 I/O 操作分布到最大数量的可用磁盘上。

  SQL Server 日志文件始终 都应该从物理上分散到不同的硬盘驱动器,与所有其他 SQL Server 数据库文件分开。对于管理多个繁忙数据库的极其繁忙的 SQL Server 来说,每个数据库的事务日志文件应当在物理上互相分离,以减少争用现象。

  由于事务日志记录主要是顺序写入 I/O,所以将日志文件分开往往会显著提高 I/O 性能。包含日志文件的磁盘驱动器可以非常高效地执行这些顺序写入操作,但前提是这些操作不被其他 I/O 请求中断。有时,将需要在 SQL Server 操作(例如,复制、回滚和延迟更新)过程中读取事务日志。有些实现通过将新数据几乎实时地装载到数据仓库中,将复制用作其数据转换实用工具的前端。参与复制的 SQL Server 的管理员需要确保所有用于事务日志文件的磁盘都有足够的 I/O 处理能力,以便处理除正常日志事务写入之外需要发生的读取操作。

  物理上分割的文件和文件组需要额外的管理工作。事实证明,为了隔离和改善对非常活动的表或索引的访问而进行分割时,这些额外的工作是值得的。下面列出了一些益处:

  对于特定对象的 I/O 需求,可以进行更准确的评估,而如果所有数据库对象都放在一个大驱动器池中,进行这种评估就不那么容易了。

  使用文件和文件组对数据和索引进行分区,可以增强管理员创建粒度更细的备份和恢复策略的能力。

  文件和文件组可用于维护数据在磁盘上的顺序放置,从而减少或消除非顺序的 I/O 活动。如果数据装载到数据仓库的可用时间窗口要求并行执行处理以满足最终期限,则该功能就变得尤其重要。

  在数据库开发和基准检验阶段,可能适于对文件和文件组进行物理分割,这样可收集数据库 I/O 信息并将其应用于生产数据库服务器环境的容量计划。

  有关对象分区的注意事项

  可以在不同的硬盘驱动器、RAID 控制器和 PCI 通道(或者三者的组合)之间分隔以下方面的 SQL Server 活动:

  事务日志

  tempdb

  数据库

  表

  非聚集索引

  注意 在 SQL Server 2000 中,Microsoft 增强了分布式分区视图,使用这种视图可以创建联合数据库(通常称作扩展),这种数据库会将资源负荷和 I/O 活动分布到多个服务器上。联合数据库适于某些高端联机分析处理 (OLTP) 应用程序,但是建议不要使用该方法来解决数据仓库的需求。

  使用硬件 RAID 控制器、RAID 热插拔驱动器和联机 RAID 扩展功能可以轻松实现对 SQL Server I/O 活动的物理分割。最灵活的方法是排列 RAID 控制器,让单独的 RAID 通道与上述不同活动方面相关联。同样,应当将每个 RAID 通道连接到一个单独的 RAID 热插拔机柜,以便充分利用联机 RAID 扩展功能(如果可通过 RAID 控制器使用该功能)。随后,Windows 逻辑驱动器盘符将会与每个 RAID 阵列相关联,并且 SQL Server 文件会基于已知的 I/O 使用模式在不同的 RAID 阵列之间被分隔开。

  使用这种配置,有可能将与每个活动相关联的磁盘队列重新与一个不同的 RAID 通道及其驱动器机柜相关联。如果某个 RAID 控制器及其驱动器阵列机柜均支持联机 RAID 扩展功能,而且机柜中有热插拔硬盘驱动器的插槽,则只需向 RAID 阵列中添加更多的驱动器,直到系统监视器报告该 RAID 阵列的磁盘队列已经达到可接受的程度(对于 SQL Server 文件最好少于两个),即可解决该 RAID 阵列的磁盘队列问题。这可以在 SQL Server 联机时完成。

  分离事务日志

  维护事务日志文件的存储设备应该在物理上与数据文件所在的设备分开。根据您的数据库恢复模型设置不同,大多数更新活动既产生数据设备活动又产生日志活动。如果将这两个活动设置为共享同一个设备,则要执行的操作将争用同一个有限资源。大多数安装都受益于将这些竞争 I/O 活动分开。

  分离 tempdb

  SQL Server 会在每个服务器实例上创建一个名为 tempdb 的数据库,以供服务器用作各种不同活动的共享工作区,这些活动包括:临时表、排序、处理子查询、生成聚合以支持 GROUP BY 或 ORDER BY 子句、使用 DISTINCT 的查询(必须创建临时工作表才能删除重复行)、游标,以及哈希联接。通过将 tempdb 分割到其自己的 RAID 通道上,我们使 tempdb I/O 操作能够与它们的相关事务的 I/O 操作并行发生。由于 tempdb 实际上是一个草稿区域,而且更新频繁,所以 RAID 5 对于 tempdb 并不是好的选择,而 RAID 1 或 0+1 提供的性能更好。虽然 Raid 0 不提供容错功能,但可以考虑将它用于 tempdb,因为每次重新启动数据库服务器时都会重新生成 tempdb。RAID 0 使用最少的物理驱动器为 tempdb 带来了最佳的 RAID 性能,但在生产环境中将 RAID 0 用于 tempdb 时主要的顾虑是:如果有物理驱动器(包括用于 tempdb 的驱动器)出现故障,就可能影响到 SQL Server 的可用性。如果将 tempdb 放在具备容错能力的 RAID 配置上,就可以避免这一点。

  要移动 tempdb 数据库,请使用 ALTER DATABASE 命令更改与 tempdb 相关联的 SQL Server 逻辑文件名的物理文件位置。例如,要将 tempdb 以及与之相关联的日志移到新文件位置 E:mssql7 和 C:temp,请使用以下命令:

alter database tempdb modify file (name='tempdev',filename=
'e:mssql7tempnew_location.mDF')
alter database tempdb modify file (name='templog',filename=
'c:temptempnew_loglocation.mDF')

  与用户数据库相比,master 数据库 msdb 和model 数据库在生产过程中很少使用,因此,在考虑优化 I/O 性能时,通常不必考虑它们。master 数据库通常只用于添加新登录、数据库、设备和其他系统对象。

  数据库分区

  可以使用文件和/或文件组对数据库进行分区。文件组只是为管理目的而将多个单独的文件组合在一起的命名集合。一个文件不能是多个文件组的成员。表、索引、text、ntext 和 image 数据都可以与一个特定的文件组相关联。这就是说,它们所有的页都是从该文件组中的文件中分配而来的。下面介绍三种类型的文件组。

  主文件组

  该文件组包含主数据文件以及未放到另一个文件组中的所有其他文件。系统表的所有页都是从主文件组分配的。

  用户定义的文件组

  该文件组是使用 CREATE DATABASE 或 ALTER DATABASEfilegroup 语句中的 FILEGROUP 关键字或者在 SQL Server 企业管理器中的属性对话框上指定的任何文件组。

  默认文件组

  默认文件组包含在创建时未指定文件组的所有表和索引的页。在每个数据库中,每次只能有一个文件组是默认文件组。如果未指定默认文件组,则主文件组就是默认文件组。

  文件和文件组对于控制数据和索引的位置以及消除设备争用现象很有用。有相当一部分安装还将文件和文件组用作一种比数据库粒度更细的机制,以便对它们的数据库备份/恢复策略进行更多的控制。

  水平分区(表)

  水平分区将一个表分割成多个表,每个表都包含相同的列数,但是行数会减少。怎样对表进行水平分区要根据分析数据的方式而定。根据一般经验,在对表进行分区时,应当使查询引用的表尽可能少。否则,用于在查询时按逻辑合并表的 UNION 查询就会过多,从而会影响性能。

  例如,假定企业要求规定:我们要将十年来不断滚动的事务数据存储到我们数据仓库的中央事实表中。我们公司十年来的事务数据意味着数据会超过十亿行。数量达到十亿的任何内容管理起来都会很困难。现在,请考虑每年我们都必须除去第十年的数据,然后装载最新一年的数据。

  管理员通常采用的方法是:创建十个独立但结构相同的表,每个表中存放一年的数据。然后,管理员在这十个表的基础上定义一个联合视图,以便让最终用户看到所有数据都放在一个表中。实际上并非如此。针对该视图执行的任何查询都被优化成只搜索指定的年份(和相应的表)。不过,管理员确实获得了管理能力。现在,管理员能够以粒度方式单独管理每年的数据。每年的数据都可以单独装载、索引或维护。添加新年份就是这样简单:除去该视图,除去包含第十年数据的表,装载和索引新年份的数据,然后重新定义新视图以包括新年份的数据。

  当您在多个表或多个服务器之间对数据进行分区时,只访问部分数据的查询运行得更快,因为要扫描的数据比较少。如果这些表位于不同的服务器上,或者在一台具有多个处理器的计算机上,还可以并行扫描查询所涉及的每个表,从而改善查询性能。另外,维护任务(例如,重建索引或备份表)的执行速度会更快。

  通过使用分区视图,数据仍显示为一个表,而且在查询数据时可以不必手动引用相应的基础表。如果满足下列任一条件,分区视图就可以进行更新。有关分区视图及其限制的详细信息,请参阅“SQL Server 联机丛书”。

  在该视图上用可支持 INSERT、UPDATE 和 DELETE 语句的逻辑定义了 INSTEAD OF 触发器。

  该视图以及 INSERT、UPDATE 和 DELETE 语句遵循为可更新的分区视图定义的规则。

  分离非聚集索引

  索引驻留在 B 型树结构中,通过使用 ALTER DATABASE 命令来设置一个不同的文件组,这些索引可以与它们的相关数据库表分开(聚集索引除外)。在下面的示例中,第一个 ALTER DATABASE 创建一个文件组。第二个 ALTER DATABASE 向新创建的文件组中添加一个文件。

alter database testdb add filegroup testgroup1
alter database testdb add file (name = 'testfile',
filename = 'e:mssql7test1.ndf') to filegroup testgroup1

  在创建了文件组及其关联的文件之后,可以在创建索引时指定该文件组,从而使用该文件组来存储索引。

create table test1(col1 char(8))
create index index1 on test1(col1) on testgroup1

  SP_HELPFILE 会将有关给定数据库中文件和文件组的信息反馈回来。SP_HELP <表名> 的输出结果中有一节,该节提供有关表的索引及其文件组关系的信息。

sp_helpfile
sp_help test1

  并行数据检索

  SQL Server 在具有多个处理器的计算机上运行时可以并行扫描数据。如果一个表在包含多个文件的文件组中,则可以对该表执行多个并行扫描。只要按顺序访问某个表,就会创建一个独立线程来并行读取每个文件。例如,如果完全扫描在包含四个文件的文件组上创建的表,将会使用四个独立线程来并行读取数据。因此,为每个文件组创建多个文件会有助于提高性能,因为这样会使用独立的线程来并行扫描每个文件。同样,当某个查询联接着不同文件组上的表时,可以并行读取每个表,从而改进查询性能。

  另外,表中的任何 text、ntext 或 image 列都可以在除基表所在文件组以外的文件组上创建。

  最终,文件过多会导致并行线程过多,进而导致磁盘 I/O 子系统中出现瓶颈,这时就会达到饱和点。通过使用系统监视器来监视 PhysicalDisk 对象和磁盘队列长度计数器,可以确定这些瓶颈。如果磁盘队列长度计数器大于 3,请考虑减少文件数量。

  为了通过使用多个文件并行访问数据来提高吞吐量,将尽可能多的数据分布到尽可能多的物理驱动器上是很有益处的。要将数据均匀地分布到所有磁盘上,请首先设置基于硬件的磁盘条带化,然后根据需要使用文件组将数据分布到多个硬件条带集上。

  并行查询建议

  SQL Server 可自动以并行方式执行查询。这样就会对在多处理器计算机上执行查询进行优化。工作会细分为多个线程(受线程和内存的可用性影响),而不是一个查询用一个操作系统线程执行,这样,完成复杂查询时就会速度更快,效率更高。

  SQL Server 中的优化器会为查询生成计划并确定将在何时并行执行查询。确定时会依据以下条件:

  计算机是否有多个处理器?

  是否有足够的内存来并行执行查询?

  服务器上的 CPU 负荷是多少?

  正在运行哪种类型的查询?

  如果允许 SQL Server 以并行方式运行并行操作(例如 DBCC 和创建索引),对服务器资源的压力就会变重,而且在执行繁重的并行操作任务时,您可能会看到警告信息。如果服务器错误日志中经常出现有关资源不足的警告消息,请考虑使用系统监视器来调查哪些资源(例如,内存、CPU 使用率和 I/O 使用率)可用。

  当服务器上有活动用户时,请不要并行运行大量查询。请尝试在没有负载的时间段中执行维护作业(例如,DBCC 和创建索引)。这些作业可以并行执行。监视磁盘 I/O 性能。观察系统监视器(在 Windows NT 4.0 中为性能监视器)中的磁盘队列长度,确定是升级硬盘还是将数据库重新分布到不同的磁盘上。如果 CPU 的使用率非常高,请升级或添加更多的处理器。

  下列服务器配置选项可能会影响查询的并行执行:

  并行度的成本阈值

  最大并行度

  最大工作线程

  查询调控器成本限制

  优化数据负荷

  在加速数据装载活动时,一定要记住多种提示和方法。根据您执行的是初始数据装载还是增量数据装载,这些方法可能会有所不同。一般来说,增量装载更复杂且限制性更强。您选择的方法可能还基于您无法控制的因素。处理窗口要求、所选存储配置、服务器硬件的限制等都会影响可供您使用的选项。

  在执行初始数据装载和增量数据装载时,有一些共同的要点需要记住。下面将详细讨论以下主题:

  选择适当的数据库恢复模型

  使用 bcp、BULK INSERT 或大容量复制 API

  控制锁定行为

  并行装载数据

  杂项,其中包括:

  绕过引用完整性检查(约束和触发器)

  装载预先排序的数据

  删除索引带来的影响

  选择适当的数据库恢复模型

  我们已在“影响性能的配置选项”一节中讨论了数据库恢复模型。一定要记住所选恢复模型对执行数据装载所需的时间可能会有很大的影响。这些恢复模型主要控制将写出到事务日志中的数据量。因为对事务日志执行写入操作基本上会使工作负荷加倍,所以这非常重要。

  日志记录和最小日志记录大容量复制操作

  在使用完全恢复模型时,由某个大容量数据装载机制(将在下面讨论)执行的所有插入行操作都记录到事务日志中。对于大型数据装载,这可能会导致快速填充事务日志。为了帮助防止事务日志的空间不足,可执行最小日志记录大容量复制操作。是以日志记录还是以无日志记录形式执行大容量复制不作为大容量复制操作的一部分来指定;它取决于大容量复制中涉及到的数据库和表的状态。如果符合以下所有的条件,将进行无日志记录的大容量复制:

  恢复模型是“简单”或“大容量日志记录的”,或者数据库选项 select into/bulkcopy 设置为真。

  目标表未在进行复制。

  目标表没有索引,或者如果目标表有索引,在开始大容量复制时它也是空的。

  TABLOCK 提示是在将 eOption 设置为 BCPHINTS 的情况下使用 bcp_control 指定的。

  任何不满足上述条件的向 SQL Server 实例中进行的大容量复制将完全记录下来。

  在执行初始数据装载时,应当总是在“大容量日志记录的”或“简单”恢复模型下运行。对于增量数据装载,只要数据丢失的可能性很低,就考虑使用“大容量日志记录的”模型。因为许多数据仓库基本上都是只读的或者事务活动的数量很少,所以将数据库恢复模型设置为“大容量日志记录的”不会产生任何问题。

  使用 bcp、BULK INSERT 或大容量复制 API

  SQL Server 内部存在两个机制,用来解决大容量移动数据的需求。第一个机制是 bcp 实用工具。第二个机制是 BULK INSERT 语句。bcp 是一个命令提示符实用工具,它既将数据复制到 SQL Server 中又从其中复制数据。在 SQL Server 2000 中,bcp 实用工具是用 ODBC 大容量复制应用程序编程接口 (API) 重新编写的。bcp 实用工具的早期版本是使用 DB-Library 大容量复制 API 编写的。

  BULK INSERT 是 SQL Server 附带的 Transact-SQL 语句,该语句可从数据库环境内执行。与 bcp 不同的是,BULK INSERT 只能将数据拉入 SQL Server 中。它不能将数据推出。使用 BULK INSERT 的一个好处在于,它可以使用 Transact-SQL 语句将数据复制到 SQL Server 的实例中,而不必退出解释器转到命令提示符中。

  第三个选项是大容量复制 API,程序员通常对该选项很感兴趣。有了这些 API,程序员就能够使用 ODBC、OLE DB、SQL-DMO 或者甚至基于 DB 库的应用程序将数据移入或移出 SQL Server。

  所有这些选项都使您能够对批处理大小进行控制。除非您使用的是小容量数据,否则最好习惯于指定批处理大小以进行恢复。如果未指定批处理大小,则 SQL Server 将所有要装载的行作为一批提交。例如,您尝试将 1,000,000 行新数据装载到某个表中。服务器在处理完第 999,999 行后突然断电。当服务器恢复时,将需要从数据库中回滚处理完的 999,999 行,然后再尝试重新装载数据。您可以通过将批处理大小指定为 10,000 来大大节省自己的恢复时间,这是由于您已经将 1 到 990,000 行提交到数据库中,因此将只需回滚 9,999 行(而不是 999,999 行)。同样,如果未指定批处理大小,则将必须从第 1 行重新启动装载处理才能重新装载数据。如果将批处理大小指定为 10,000 行,则只需从第 990,001 行重新启动装载处理,这样就高效地绕过了已经提交的 990,000 行。

  控制锁定行为

  bcp 实用工具和 BULK INSERT 语句接受 TABLOCK 提示,该提示允许用户指定要使用的锁定行为。TABLOCK 指定在大容量复制操作过程中将采用大容量更新表级锁。使用 TABLOCK 可以减少表上对锁的争用,从而改进大容量复制操作的性能。当针对单个表处理并行装载时,该设置有非常重要的含义(将在下一节讨论)。

  例如,要将 Authors.txt 数据文件中的数据大容量复制到 pubs 数据库中的 authors2 表中,请指定表级锁,并从以下命令行提示符执行:

  bcp pubs..authors2 in authors.txt -c -t, -Sservername -Usa -Ppassword -h "TABLOCK"

  或者,您可以从查询工具(如 SQL 查询分析器),使用 BULK INSERT 语句来大容量复制数据,如下例所示:

BULK INSERT pubs..authors2 FROM 'c:authors.txt'
WITH (
DATAFILETYPE = 'char',
FIELDTERMINATOR = ',',
TABLOCK
)

  如果未指定 TABLOCK,除非对于表将 table lock on bulk load 选项设置为 on,否则默认锁定会使用行级锁。将 table lock on bulk load 选项与 sp_tableoption 命令一起使用,也可以设置大容量装载操作过程中表的锁定行为。

Table lock on bulk load表的锁定行为
Off使用行级锁
On使用表级锁

  注意 如果指定了 TABLOCK 提示,则在大容量装载过程中,它将替代使用 sp_tableoption 声明的设置。

  并行装载数据

  并行装载 — 非分区表

  使用 SQL Server 中的任一大容量数据装载机制,都可以将数据并行装载到一个非分区表中。这是通过同时运行多个数据装载来完成的。在开始装载之前,需要将要并行装载的数据拆分成多个独立文件(大容量插入 API 的数据源)。然后,可同时启动所有的独立装载操作,以便并行装载数据。

  例如,假设您需要为在全球四个地区运作的服务公司装载合并的数据库,每个地区每个月都报告寄给客户的帐单上的报告时间(小时)。对于大型服务组织,这可能表示需要合并大量事务数据。如果这四个报告地区都分别提供独立文件,则可以使用上面介绍的方法将这四个文件同时装载到一个表中。

  注意 并行处理的并行线程(装载)的数量不应超过 SQL Server 的可用处理器数。

  下面的插图说明了对非分区表进行的并行装载。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  并行装载:水平分区(表)

  本节重点介绍如何使用水平分区表来提高数据装载的速度。在上一节中,我们讨论了将数据从多个文件装载到一个(非分区)表中。如果对表进行水平分区,则可以减少设备争用现象,从而有机会改善数据的连续性并加速装载过程。虽然上图显示的是数据装载到了表的不同部分中,但这样的表述可能不准确。如果上述装载中的所有三个线程是同时处理的,为该表提取的扩展盘区最后就可能会是混合状态。在数据混合后,可能导致在检索数据时无法实现最佳性能。这是由于数据不是按物理上连续的顺序存储的,从而可能导致系统使用不连续的 I/O 访问它。

  在该表基础上生成聚集索引将解决上述问题,因为数据会按连续顺序被读入、按键顺序排序,并被回写。但是,读取、排序、删除旧数据以及将新排序的数据回写可能是一项非常耗时的任务(请参阅下面的装载预先排序的数据)。为避免出现这种混合的情形,请考虑使用文件组在可以存储大表的位置保留多块连续空间。许多安装还使用文件组将索引数据与表数据分开。

  为便于阐述,假定有一个数据仓库分配在一个大型物理分区上。任何对该数据库并行执行的装载操作都有可能导致以非连续(混合)状态存储受影响的数据/索引页。将执行哪种操作?任何对数据进行修改的操作都将导致数据变得不连续。为了满足处理窗口的要求,用户可能会尝试并行执行初始数据装载、增量数据装载、索引创建、索引维护、插入、更新、删除等活动。

  下面的插图显示的是跨多个文件组对表分区。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  装载预先排序的数据

  SQL Server 的早期版本提供了一个选项,您可以在创建索引时用它来指定 SORTED_DATA 选项。SQL Server 2000 取消了这个选项。在早期版本中,将该选项指定为 CREATE INDEX 语句的一部分是:它能够让您在索引创建过程中避免排序的步骤。默认情况下,在 SQL Server 中创建聚集索引时,表中数据会在处理过程中排序。要在 SQL Server 2000 中获得同样的效果,请考虑在大容量装载数据之前创建聚集索引。SQL Server 2000 中的大容量操作使用了增强的索引维护策略,这样,对于已具有聚集索引的表,可以改进数据导入性能,而且在导入之后不需要对数据重新排序。

  FILLFACTOR 和 PAD_INDEX 对数据装载的影响

  FILLFACTOR 和 PAD_INDEX 将在题为“索引和索引维护”的一节中更完整地介绍。对于 FILLFACTOR 和 PAD_INDEX,都需要记住关键的一点:创建索引时,如果将它们保留为默认值设置,可能会导致 SQL Server 为存储数据而执行比必需数量多的写入和读取 I/O 操作。如果数据仓库中没有发生多少写入活动但发生了大量读取活动,则更是如此。要让 SQL Server 在一页数据页或索引页中写入更多的数据,您可以在创建索引时指定特定的 FILLFACTOR。最好在提供覆盖 FILLFACTOR 值时指定 PAD_INDEX。

  初始数据装载的一般准则

  在装载数据时

  删除索引(唯一的例外可能是在装载预先排序的数据时,请参阅上文)

  使用 BULK INSERT、bcp 或大容量复制 API

  使用分区数据文件并行装载到分区表中

  对于每个可用的 CPU 运行一个装载流

  设置“大容量日志记录的”或“简单”恢复模型

  使用 TABLOCK 选项

  在装载数据之后

  创建索引

  切换到相应的恢复模型

  执行备份

  增量数据装载的一般准则

  用索引将数据装载到适当位置。

  应当根据性能和并发要求来确定锁定粒度 (sp_indexoption)。

  除非特别需要保留时点恢复(例如,联机用户在大容量装载过程中修改数据库),否则请将恢复模型从“完全”更改为“大容量日志记录的”。读取操作不应当影响大容量装载。

  索引和索引维护

  前面已经讨论了服务器硬件设备的 I/O 特征。现在,我们将讨论 SQL Server 数据和索引结构在物理上是如何放置在磁盘驱动器上的。如果要在设计完成之后改善性能,则索引位置有可能是影响数据仓库的一个最大因素。

  SQL Server 中的索引类型

  虽然 SQL Server 2000 引入了几种新索引类型,但它们全部都基于两个核心窗体。这两个核心窗体的格式是聚集索引或非聚集索引。在 SQL Server 中,数据库设计人员可以使用以下两种主要类型的索引:

  聚集索引。

  非聚集索引。

  这两个主要类型的其他变体包括:

  唯一索引。

  计算列的索引。

  索引视图。

  全文索引。

  以下各节将详细介绍上面提到的每种索引(全文索引除外)。全文索引是一种特殊情况,它与其他数据库索引不同,本章不对它进行介绍。索引视图是 SQL Server 2000 中新引入的一种索引,它应该会引起数据仓库用户的特别关注。SQL Server 2000 中引入的另一项新功能是按升序或降序创建索引。

  索引的工作原理

  数据库中的索引类似于图书中的索引。在一本书中,您使用索引可以迅速找到信息,而不必读完全书。在一个数据库中,数据库程序使用索引可以找到表中的数据,而不必扫描整个表。书中的索引是一个字词以及各字词所在页码的列表。数据库中的索引是表中的值以及各值存储位置(在表中所在的行)的列表。

  索引可以针对表中的一列或一组列创建,并以 B 树的形式实现。索引包含一个条目以及一个或多个对应于表中每一行的列(搜索键)。B 树根据搜索键的排序次序按升序或者降序(视创建索引时所选选项而定)存储,利用该搜索键的任何前导子集,可以高效地搜索到 B 树。例如,利用以下组合,可以高效地搜索 A、B、C 列的索引:A;A 和 B;A、B 和 C。

  当您创建数据库并优化其性能时,应当为查询中使用的列创建用来查找数据的索引。在 SQL Server 附带的 pubs 示例数据库中,在 employee 表的 emp_id 列有一个索引。当用户执行的语句根据指定的 emp_id 值在 employee 表中查找数据时,SQL Server 查询处理器识别 emp_id 列的索引并使用该索引来查找数据。下面的插图说明了该索引如何存储每个 emp_id 值并指向表中具有相应值的数据所在的行。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  但是,带索引的表需要在数据库中占用更多的存储空间。同样,用来插入、更新或删除数据的命令的运行时间以及维护索引所需的处理时间会更长。您在设计和创建索引时,一定要注意:性能益处比存储空间和处理资源所导致的额外成本更加重要。

  索引交集

  SQL Server 查询处理器中有一项独特的功能:执行索引交集。这是一种特殊形式的索引覆盖,我们将在以后详述,但是现在因以下两个原因而需要提及索引交集。第一,它是一种可能会影响您的索引设计策略的技术。

  第二,该技术可能会减少您需要的索引数,从而可以大大节省大型数据库占用的磁盘空间。

  索引交集允许查询处理器使用多个索引来解决查询。大多数数据库查询处理器在尝试解决查询时都只使用一个索引。SQL Server 可以组合给定表或视图中的多个索引,基于这些索引生成哈希表并利用哈希表来减少给定查询的 I/O 操作。就本质而言,从索引交集中生成的哈希表变成了覆盖索引,而且,它提供的 I/O 性能与覆盖索引提供的相同。在数据库用户环境中,很难预先确定将针对该数据库运行的所有查询,而索引交集为这种环境提供了更大的灵活性。在这种情况下,较好的策略是针对所有经常会被查询的列定义单列的非群集索引,并让索引交集处理来需要覆盖索引的情形。

  下面的示例使用了索引交集:

Create index Indexname1 on Table1(col2)
Create index Indexname2 on Table1(col3)
Select col3 from table1 where col2 = 'value'

  在执行上面的查询时,可以通过组合这些索引来快速高效地解决该查询。

  SQL Server 中的索引结构

  SQL Server 中所有的索引在物理上都是基于存储在 8 KB 索引页上的 B 树索引结构构建的。每个索引页都有一个页头,页头后面是索引行。每个索引行都包含一个键值和一个指向行级索引页或实际数据行的指针。索引中的每一页又被称作一个索引节点。B 树的顶层节点被称作根节点。索引中的底层节点被称作叶节点。根和叶之间的任何索引层都统称为中级层或节点。每层索引中的页都在双向链接列表中链接在一起。

  SQL Server 数据页和索引页的大小均为 8 KB。SQL Server 数据页包含所有与表中某行关联的数据(文本和图像数据可能除外)。就文本和图像数据而言,在默认情况下,包含与该文本或图像列关联的行的 SQL Server 数据页将包含一个指针,该指针指向一个或多个包含该文本或图像数据的 8 KB 页的二进制树(或 B 树)结构。SQL Server 2000 中的一个新功能是能够将小型文本和图像值存储在行中,这意味着小型文本或图像列将存储在数据页上。因为可以避免提取相应的图像或文本数据所必需的额外 I/O,所以该功能可以减少 I/O 操作。有关如何将表设置为在行中存储文本或图像的信息,请参阅“SQL Server 联机从书”。

  聚集索引

  聚集索引对于从表中检索一定范围的数据值非常有用。非聚集索引最适于检索特定行,而聚集索引最适于检索一定范围的行。但是,由于每个表只允许使用一个聚集索引,因此按照这个简单的逻辑来确定要创建哪种类型的索引并不总能成功。对于该问题有一个简单的物理原因。对于聚集索引 B 树结构的上部(非叶层),如果像对它们的非聚集索引部分那样组织,则聚集索引的底层由表的实际 8 KB 数据页组成。但这种情况有一个例外,那就是在视图的基础上创建聚集索引时。因为将在下面介绍索引视图,所以我们将讨论针对实际表创建的聚集索引。在针对表创建聚集索引时,会按与索引搜索键相同的顺序读取与该表关联的数据、对这些数据进行排序,并会在物理上将它们存回数据库。因为该表的数据只能按照一种顺序保存到存储器中,不会导致重复,所以符合一个聚集的限制。

  下图描述了聚集索引的存储器。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  聚集索引和性能

  聚集索引有一些会影响性能的固有特征。

  在使用聚集索引根据搜索键来检索 SQL Server 数据时,不需要指针跳转(会导致硬盘上的位置可能不按顺序更改)来检索关联的数据页。这是由于聚集索引的叶层实际上就是关联的数据页。

  如前所述,叶层(当然也包括表或索引视图的数据)在物理上会按照与搜索键相同的顺序进行排序和存储。因为聚集索引的叶层包含表的实际 8 KB 数据页,所以整个表的行数据会按照由聚集索引确定的顺序以物理方式排列在磁盘驱动器上。这就会在根据聚集索引的值从该表中提取大量行(至少大于 64 KB)时带来潜在的 I/O 性能优势,因为使用的是顺序磁盘 I/O(除非该表上发生了页拆分,这种情况将在题为“FILLFACTOR 和 PAD_INDEX”的一节中讨论)。正因为如此,所以在检索大量行时,一定要根据将用于执行范围扫描的列来对表选取聚集索引。

  表中与聚集索引相关联的行必须按照与索引搜索键相同的顺序排序和存储,这一点具有以下意义:

  在您创建聚集索引时,表会被复制,表中的数据会被排序,然后,原来的表会被删除。所以,数据库中必须有足够的空闲空间来存放数据的副本。

  在默认情况下,会在创建索引时对表中的数据进行排序。但是,如果数据已按正确顺序排过序,则会自动跳过排序操作。这样就可以显著加快索引创建过程。

  将数据装载到表中时的顺序应尽可能与您计划用于生成聚集索引的搜索键的顺序相同。对于大表(例如那些通常会成为数据仓库特征的表),该方法将大大加速索引创建过程,从而缩短您处理初始数据装载所需的时间。只要表中的行仍保持未创建聚集索引时所排的顺序,就可以在除去和重建聚集索引时可以使用该方法。任何行排序有误,操作都会被取消,会出现相应的错误信息,而且不会创建索引。

  同样,针对排过序的数据生成聚集索引时所需要的 I/O 也少得多,这是因为不必复制数据、对数据进行排序、将数据存回数据库,然后删除旧表数据,而是会将数据留在原来分配给它的扩展盘区中。索引扩展盘区只是添加到数据库中来存储顶层节点和中间节点。

  注意 针对大表生成索引的首选方法是:先生成聚集索引,然后生成非聚集索引。这样,就不会因为数据移动而需要重新生成非聚集索引。在除去所有索引时,首先会除去非聚集索引,最后除去聚集索引。这样,就不需要重新生成索引。

  非聚集索引

  非聚集索引最适于根据特定的键值,从大型 SQL Server 表中提取少数几个具有良好选择性的行。如前所述,非聚集索引是由 8 KB 索引页形成的二进制树。索引页二进制树的底层或叶层包含组成该索引的列中的所有数据。在使用非聚集索引根据键值的匹配项从表中检索信息时,会遍历索引的 B 树,直到在索引的叶层找到键的匹配项。如果需要表中不构成索引的列,指针就会跳转。这种指针跳转将有可能需要针对磁盘执行非顺序 I/O 操作。它甚至可能需要从另一磁盘中读取数据,尤其是在表及其伴随的索引 B 树很大时。如果多个指针指向同一个 8 KB 数据页,对 I/O 性能的影响就会比较小,因为只需将该页读入数据缓存一次。如果 SQL 查询涉及到用非聚集索引进行搜索,则对于对该查询返回的每一行,至少需要一次指针跳转。

  注意 由于指针每次跳转都会带来与之相关的开销,因此非聚集索引更适于处理从表中只返回一行或几行的查询。聚集索引更适于处理需要一系列行的查询。

  下图说明了非聚集索引的存储。请注意,添加的叶层指向对应的数据页。在使用非聚集索引而不是聚集索引来访问表数据时,添加的指针跳转就会在那里起作用。有关非聚集索引的更多信息,请参阅“SQL Server 联机丛书”。

数据仓库的 RDBMS 性能优化指南(1)

  如果您的浏览器不支持嵌入式框架,请单击此处在单独的页中查看。

  唯一索引

  聚集索引和非聚集索引均可用于强制表内的唯一性,方法是在现有表上创建索引时指定 UNIQUE 关键字。确保表内唯一性的另一种方法是使用 UNIQUE 约束。如同唯一索引,UNIQUE 约束强制一组列中各值的唯一性。实际上,UNIQUE 约束的赋值自动创建基础唯一索引,以利于强制该约束。由于唯一性可以作为 CREATE TABLE 语句的一部分来加以定义和记录,因此,UNIQUE 约束通常优先于单独唯一索引的创建。

来源:Microsoft Tech Net    责编:豆豆技术应用

正在加载评论...