最有效的数据库管理员不会根据表面上看起来很明显的东西做出草率的决定。他们更深入地研究问题,以便在采取行动之前更好地了解根本原因。
这是优化 SQL Server 的一种非常重要的方法。以下是我看到的前五个 SQL Server 性能问题,以及为什么永远不要草率假设并对所有事情应用批判性镜头很重要。
1. Tempdb PAGELATCH 争用
这个日益普遍的问题通常是由于系统大量使用 tempdb 进行某种类型的提取、转换和加载 (ETL) 过程。如果它是一个持续的“实时”风格的 ETL 过程,这尤其常见。
症状可能会有所不同,但有些事情总是相同的:tempdb 中的高 PAGELATCH 等待和使用 tempdb 的进程记录的性能不佳。我通常会遵循 Performance Advisor 中对 Top SQL 的等待,并查看大量使用 Top SQL 中列出的临时表的查询。这些查询通常以毫秒为单位运行,并且永远不应计入服务器的“顶级 SQL”。这可能会让人们觉得这些查询是问题的很大一部分,但事实并非如此。查询是真正问题的受害者。
一旦怀疑是这种情况,我通常会跳转到 Performance Advisor 中的“磁盘活动”选项卡以查看 tempdb 的配置方式。大多数时候我实际上看到的是同样的事情:一个繁忙的临时数据库,定义了一个数据文件。从这里开始,我通常会建议重新配置 tempdb。
2. 期待自动更新统计信息以保持统计更新
这里的问题是触发自动统计更新的阈值在大多数情况下最终是相同的,即使对于非常大的表也是如此。阈值约为表中行的 20%。在一个非常大的表上,需要大量数据更改才能触发更新。
之所以列出该列表,是因为数据库管理员似乎真的很惊讶地发现自动更新并没有像顾名思义那样处理事情。然后也有许多 DBA 认为应该由他们的维护工作来处理。然后在查看维护后,他们大部分时间都在进行索引重组,这也不会更新统计信息(尽管重建会)。
教训是密切关注统计数据并确保它们定期更新,尤其是在越来越普遍的大表上。另一种选择是使用跟踪标志 2371 来实际更改用于触发更新的公式。
3. CXPACKET 等待类型
这是我在大型 SQL Server 系统上看到的一种最常见的等待类型,当有人让我研究它们的查询性能时。
可悲的是,我仍然看到很多人做出最初的假设,即应该通过让查询或整个 SQL Server 将最大并行度 (MAXDOP) 设置为 1 来解决问题。 通常,可以通过适当的索引来处理问题或统计维护。也可能是为此查询缓存的计划不是最佳的,您可以使用 sp_recompile 将其标记为重新编译,在查询级别设置重新编译,或者只是使用带有计划句柄的 DBCC FREEPROCCACHE 驱逐计划。最好在决定将 MAXDOP 更改为 1 之前用尽这些选项,因为您可能会在没有意识到的情况下丢弃大量处理能力。
4. 误解“超时在...完成之前到期”
这个是巨大的。除了一些非常极端的行为之外,您可能会为 SQL Server 处理两种基本类型的超时。这些是连接超时和操作(或查询)超时。在这两种情况下,这些值都是由连接到 SQL Server 的客户端设置的。在服务器端,有一个远程查询超时设置,但这是非常极端的情况。
操作超时是最常见的,也可能是我遇到的最容易被误解的情况。原因归结为一个简单的因素:执行命令的客户端设置了等待命令完成的最长时间。如果在完成之前达到此最大值,则中止命令。从客户端引发错误。
通常,超时错误会引发恐慌模式,因为错误看起来很吓人。实际情况是,这与在 SQL Server Management Studio 中点击停止按钮没有太大区别,因为查询花费的时间太长。它将在错误 = 2(中止)的探查器跟踪中显示完全相同。
像这样的超时告诉我们查询花费的时间比预期的要长。我们应该进入“性能调整”模式而不是“某些东西坏了”模式。来自客户端的错误信息是关于您可以开始集中调整工作的位置的好信息。
对于将 RDBMS 用于存储库的任何系统来说都是如此。您的数据库时不时地需要一些 TLC。没有它,您可能确实会遇到客户的一些超时。我们花费大量时间在查询发布之前对其进行性能优化,但适当的维护将确保它们继续按预期运行。
5. 内存压力
这是一个很大的问题,因为我经常看到它,也因为它经常被误认为磁盘性能不佳。
SQL Server 中有很多缓存,但最著名的是数据缓存(又名缓冲池)。描述数据缓存最简单的方式是它是存储在内存中的数据,而不是持久化到磁盘。将大量数据长期存储在内存中是可取的,因为在内存中处理数据通常比必须执行物理 I/O 快得多。
通常,记忆压力表现为几种不同的症状。当单独查看时,其中一些症状可能会导致您得出错误的、有时代价高昂的结论。
两个误导性症状是您可能会开始看到整个磁盘子系统的延迟高于正常延迟,并且您可能会开始看到与磁盘活动相关的异常高等待。如果您只查看这两个症状,您可能会得出结论,您需要在您的磁盘系统上工作。
这就是为什么在一个仪表板上显示所有相关指标如此重要的原因。您必须着眼于更大的图景,将与内存相关的数据与磁盘活动和等待一起可用,有助于更清晰地了解真正发生的情况。
通常,我会看到此服务器的 PLE(页面预期寿命)相当低。缓冲区缓存越大,PLE 的“临界”阈值就越高。流入和流出缓冲区的数据越多,发生“流失”时的情况就越糟。另一个考虑因素是非均匀内存访问 (NUMA)。当涉及多个 NUMA 节点时,计算 PLE 计数器的方式可能会导致此值非常具有误导性。
我通常还会看到持续较高的惰性写入器活动和 SQL Server 页面错误(SQL Server 进入磁盘)。有时我会看到我所说的缓冲区撕裂。当数据缓冲区上下波动时会发生这种情况,经常在 Performance Advisor 的历史图表上创建锯齿状(或撕裂)边缘。我还可能看到异常大的计划缓存减少了数据缓存的可用内存。
所有这些因素共同构成了记忆压力。有多种方法可以处理它们,但重要的是这不是磁盘问题。我不会根据这种情况打电话给您的存储区域网络联系人并订购新硬件。一旦控制了内存压力情况,SQL Server 就不需要那么多去磁盘了,一些与磁盘相关的症状可能会完全消失!
结论
随着组织面临新的数据库需求,首要的 SQL Server 性能问题/主题将继续发展。如果从所有这些潜在问题中得出一个主要结论,那就是始终考虑性能的全貌,因为脱离上下文查看一个因素可能会严重限制您对解决方案的选择。