摘要
Microsoft SQL Server 2005 使用高分辨率 CPU 计数器来提供微秒计时功能。 微秒是百万分之一秒 (或千分之一毫秒) 。 但是,如果使用改变 CPU 频率的技术,则 SQL Server 计时值可能不正确。 例如,使用以下任何技术时可能会出现此问题:
- CPU 步进
- AMD Cool'n'Quiet 技术
- 各种电源方案
本文包含可帮助你解决此问题的方法和其他信息。
症状
使用 SET STATISTICS TIME 语句显示服务器执行、分析和编译时间时,可能会获得不正确的值。 例如,你可能会注意到,SQL Server 执行时间的已用时间远大于 CPU 时间。 此问题可能会影响性能优化的准确性。 当您使用服务器上“摘要”部分中列出的技术之一时,会出现此问题。
原因
出现此问题的原因是,在使用这些技术时 CPU 频率发生了变化。 SQL Server 2005 使用高分辨率 CPU 计数器来提供微秒计时功能。 如果更改 CPU 频率以节省能源和减少热量输出,则计算的持续时间可能不正确。
解决方法
Service Pack 信息
要解决此问题,请获取 SQL Server 2005 的最新 Service Pack。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
913089 如何获取最新的 SQL Server 2005 Service Pack
注意 在 SQL Server 2005 Service Pack 3 和更高版本的 Service Pack 中,不使用处理器时间戳。 这些版本的 SQL Server 2005 使用更可靠的计时器,最大精度为 1 毫秒。
状态
此问题已首次在 SQL Server 2005 Service Pack 3 中更正。
解决方法
SQL Server 2005 需要已知和稳定的数据点来执行准确的性能优化。 如果在计算机上启用了动态 CPU 频率调整,则可以禁用它们,以便 CPU 在开始监视和优化 SQL Server 性能之前保持稳定的频率。 为此,请使用以下方法。
配置计算机上的电源方案,强制 CPU 保持在最大频率
请按以下步骤完成此操作:
单击 “开始”,单击 “运行”,键入 Powercfg.cpl,然后单击 “确定”。
在“电源选项属性”对话框中,单击“电源方案”列表中的“Always On”。
单击“确定”。
可能会发生偏移。 偏移是 CPU 频率值之间的差异。 有关更多信息,请参阅“偏移”部分。 在这种情况下,必须在更改电源方案后重新启动 Microsoft Windows 以重新同步所有 CPU 的频率。
如果无法重启计算机,请启用 SQL Server 处理器关联以防止 SQL Server 工作线程在 CPU 之间移动。 这样,即使 CPU 频率值之间出现差异,也无需重启计算机。 若要为服务器上的所有 CPU 启用 SQL Server 处理器关联,必须使用不同的掩码,具体取决于服务器上的逻辑处理器数。
下表列出了示例方案。
| CPU 数量 | 启用处理器相关性的语句 |
|---|---|
| 02 个 CPU | exec sp_configure 'affinity mask', 0x00000003 GO 重新配置 GO |
| 04 个 CPU | exec sp_configure 'affinity mask', 0x0000000F GO 重新配置 GO |
| 08 个 CPU | exec sp_configure 'affinity mask', 0x000000FF GO 重新配置 GO |
| 16 个 CPU | exec sp_configure 'affinity mask', 0x0000FFFF GO 重新配置 GO |
| 32 个 CPU | exec sp_configure 'affinity mask', 0xFFFFFFFF GO 重新配置 GO |
注意:在 BIOS 级别禁用 CPU 频率变化功能可能还不够。 各种第三方实用工具可以更改 CPU 频率。 某些实现即使 CPU 处于最大功率方案设置下,也可以进行频率调整。 在这种情况下,在 SQL Server 2005 中执行性能优化时必须禁用这些第三方实用工具。
使用第三方实用工具和驱动程序同步 CPU 频率和 CPU 时钟计数器
在极少数情况下,系统可能需要制造商进行更新以更正 CPU 频率问题。 如果怀疑系统可能有问题,最佳做法是检查系统中是否有最新的 BIOS、微码和固件更新。
详细信息
Microsoft SQL Server 2000 和早期版本的 SQL Server 使用 Windows 计时机制。 计时机制使用毫秒精度值。 通常,此精度为 10 到 15 毫秒。 但是,精度可能高达 55 毫秒。 SQL Server 查询经常在个位数毫秒或微秒的时间跨度内完成。 此精度需要高分辨率计时器。 因此,这些版本的 SQL Server 将某些查询的持续时间报告为 0 毫秒。 因此,在早期版本的 SQL Server 中,很难监视性能和调整 SQL Server 性能。
SQL Server 2005 通过使用高分辨率 CPU 计数器提供微秒计时功能来提高准确性。 当您使用“摘要”部分中列出的技术时,报告的计时值可能不正确。
此问题可能会影响以下对象和功能:
跟踪事件:
注意事件
存储过程节点中的事件
TSQL 节点中的事件
“对象”节点中的事件
事务节点中的事件
动态管理视图:
sys.dm_exec_query_stats
sys.dm_exec_requests
sys.dm_exec_sessions
sys.dm_io_pending_io_requests
sys.dm_os_ring_buffers
sys.dm_os_sys_info
sys.dm_io_virtual_file_stats
sys.dm_os_wait_stats
SET STATISTICS TIME 语句
sysprocesses 系统表
在安装 SQL Server 2005 Service Pack 2 (SP2) 后,当 SQL Server 检测到高分辨率计时器在 CPU 之间不同步时,SQL Server会在错误日志中记录错误消息。 错误消息表明性能计时可能不准确,用户应谨慎使用性能数据。
错误消息的文本类似于以下错误消息之一:
错误消息 1
注意
计划程序 ID 2 上 CPU 的时间戳计数器与其他 CPU 不同步。
错误消息 2
注意
CPU 时间戳频率已从 191469 刻更改为每毫秒 1794177 刻。 将使用新的频率
SQL Server使用实时戳计数器 (RDTSC) 指令获取 64 位 CPU 滴答计数。 可将此值除以 CPU 频率,以将值转换为毫秒值。 当 CPU 频率发生变化或发生偏移时,可能会发生时序变化。
CPU 步进
CPU 步进定义为 CPU 频率的故意更改。 CPU 步进也称为 Intel SpeedStep 技术或 AMD PowerNow! 技术。 发生 CPU 步进时,CPU 速度可能会以小至 50 MHz 的增量增加或减少,以节省能源和减少热量输出。 在 NUMA) 节点 (相同的非均匀内存访问中的 CPU 不会独立调整频率。
下表说明 CPU 步进更改可能如何影响计时计算。
| 采取行动的 | RDTSC 时钟周期 | 每毫秒刻数 (频率) | 挂钟时间 |
|---|---|---|---|
| 开始批处理 | 1 | 200 | 0 |
| 降频 | 200 | 100 | 1 毫秒 |
| 结束批处理 | 500 | 3 毫秒 | |
| 总数 | 500 | 4 毫秒 |
SQL Server 在开始和结束 RDTSC 时钟周期处捕获 RDTSC 时钟周期。 然后,SQL Server 将刻度除以频率值。
在此示例中,当使用频率值 200 或 100 时,会发生以下计时计算:
频率 200:500/200 = 2.5 毫秒
频率 100:500/100 = 5 毫秒
两个计时计算都与 4 毫秒的实际时钟时间不匹配。
如果在 RPC:Completed 跟踪事件中使用此计算,则会错误地报告持续时间和结束时间数据列。 RPC:Completed 事件捕获起始时钟时间和 CPU 计时。 为了在 SQL Server 2005 中获得比 Windows 提供的更高的分辨率计时,使用已用 CPU 滴答计数计算 SQL Server 跟踪中的持续时间和结束时间数据列。 结束时间列是通过将持续时间列添加到开始时间列来计算的。 在此示例中,结束时间列的计算方式是错误地将 2.5 毫秒或 5 毫秒添加到开始时间。
偏移
偏差是 CPU 时钟值的差异。 具有多个 CPU 的系统可以在同一时间点生成不同的 CPU 时钟值。 尽管这种情况并不常见,但随着时间的推移,CPU 可能会遇到时钟分离。
下面的示例演示了偏移更改如何影响 SQL Server 跟踪中持续时间数据列的结果。 该示例假定 CPU 频率稳定在每毫秒 200 个时钟周期。 下表演示了此方案中的事件。
| 采取行动的 | Windows 计划 CPU | CPU 1 RDTSC | CPU 2 RDTSC | 挂钟时间 |
|---|---|---|---|---|
| 开始批处理 | 1 | 100 | 1100 | 0 |
| 结束批处理 | 2 | 900 | 1900 | 4 ms |
| 总数 | 4 ms |
SQL Server 在起点和终点捕获 RDTSC 时钟周期。 然后,SQL Server 将 RDTSC 刻除以频率值。 在此示例中,Windows 在两个不同的 CPU 上调度了 SQL Server 工作线程。 为批处理提供服务的 SQL Server 个工作线程首先在第一个 CPU (CPU 1) 上运行。
但是,批处理执行在某个时间点中断,SQL Server 将批处理执行发送到挂起队列。 当 SQL Server 将服务于此批处理的 SQL Server 工作线程再次发送到可运行队列时,Windows 调度了在第二个 CPU (CPU 2) 上运行的线程。 SQL Server 工作线程已在 CPU 2 上完成运行。 由于 CPU 偏移,从 CPU 2 捕获的结束刻度值为 1900,而不是 900。 如果启用 SQL Server 处理器关联,则可以避免此行为。
本例中使用了以下计时计算:
- 不正确但报告的值: (1900 – 100 = 1800) / 200 = 9 毫秒
- 正确值: (900 – 100 = 800) / 200 = 4 毫秒
RPC:Completed 事件的持续时间列的值将报告为 9 毫秒而不是 4 毫秒。 此结果是正确值 4 毫秒的两倍多。
偏移警告消息已添加到 SQL Server 2005,以指示前面提到的性能输出可能不可靠。 在某些未发现的情况下,SQL Server 2005 SP2 可能会报告有关以下内容的警告消息:
- 错误偏移警告消息
- 漂移可以变成几十毫秒,而不会引起明显的系统影响
在评估与性能相关的输出以及将与性能相关的输出与时钟计时进行比较时,您必须小心。 如果没有其他性能问题的迹象,您通常可以忽略偏移警告消息。 例如,在以下情况下通常可以忽略偏移警告消息:
- 进程按预期运行。
- SQL Server 查询没有以奇怪的持续时间模式运行。
- 看不到其他瓶颈的迹象。
但是,在忽略偏移警告消息之前,我们建议你与制造商联系以确保不存在已知的 RDTSC 问题。
可以使用跟踪标志 8033 (–T8033) 返回到 SQL Server 2005 原始发行版和 SQL Server 2005 SP1 中的报告行为。 SQL Server 2005 和 SQL Server 2005 SP1 的原始发行版不报告偏移警告消息。 如果运行 SQL Server 2005 或 SQL Server 2005 SP1 的原始发行版没有问题,则通常可以忽略这些消息。
为什么 WAITFOR DELAY 语句可以正常工作? 定期系统过程呢?
超时机制不受高分辨率设计的影响。 SQL Server 不对基于计时器的活动使用高分辨率计时器。 某些超时活动基于使用 GetTickCount 函数的降低分辨率计时器。 这些超时活动包括锁定超时、WAITFOR DELAY 语句和死锁检测。
有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
938448 如果服务器使用双核 AMD Opteron 处理器或多处理器 AMD Opteron 处理器,则基于 Windows Server 2003 的服务器可能会遇到时间戳计数器偏移
895980 使用 QueryPerformanceCounter 函数的程序在 Windows Server 2003 和 Windows XP 中可能性能不佳
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。