摘要
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 频率调整,则可以禁用它们,以便在开始监视和优化性能SQL Server之前 CPU 保持稳定的频率。 为此,请使用以下方法。
在计算机上配置电源方案,以强制 CPU 保持最大频率
请按以下步骤完成此操作:
单击 “开始”,单击“ 运行”,键入“Powercfg.cpl”,然后单击“ 确定”。
在“电源选项属性”对话框中,单击“电源方案”列表中的“Always On”。
单击“确定”。
可能会发生偏移。 偏移是 CPU 频率值之间的差异。 有关详细信息,请参阅“偏移”部分。 在这种情况下,必须重启Microsoft Windows,以在更改电源方案后重新同步所有 CPU 的频率。
如果无法重新启动计算机,请启用SQL Server处理器相关性,以防止SQL Server工作线程在 CPU 之间移动。 执行此操作时,即使 CPU 频率值之间存在差异,也不必重新启动计算机。 若要为服务器上的所有 CPU 启用SQL Server处理器相关性,必须使用不同的掩码,具体取决于服务器上的逻辑处理器数量。
下表列出了示例方案。
| CPU 编号 | 用于启用处理器相关性的语句 |
|---|---|
| 02 个 CPU | exec sp_configure“关联掩码”,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“相关性掩码”,0x0000FFFF GO 配置 GO |
| 32 个 CPU | exec sp_configure“关联掩码”,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 计数器提供微秒计时功能来提高准确度。 使用“摘要”部分中列出的技术时,报告的计时值可能不正确。
此问题可能会影响以下对象和功能:
跟踪事件:
Attention 事件
“存储过程”节点中的事件
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 毫秒 |
| 总数 | 4 毫秒 |
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 处理器,则基于 2003 Windows Server的服务器可能会遇到时间戳计数器偏移
895980 使用 QueryPerformanceCounter 函数的程序在 Windows Server 2003 和 Windows XP 中性能不佳
本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 不对这些产品的性能或可靠性提供任何明示或暗示性担保。