Microsoft 以一个可下载文件的形式分发 Microsoft SQL Server 2008 R2 修补程序。 由于修补程序是累积的,因此每个新版本都包含了以前的 SQL Server 2008 R2 修补程序版本附带的所有修补程序和所有安全修补程序。
症状
请考虑以下情况:
-
应用程序运行在 Microsoft SQL Server 2008 和 Microsoft SQL Server 2008 R2 中引用某些临时表的查询。 临时表在会话中创建,而不是在存储过程中创建。
-
查询计划已缓存。
-
许多用户在高度并发环境中运行同一查询。例如,许多用户使用运行以下查询的应用程序:
create table #x (col1 int) go insert into #x values (1) go select * from #x where col1 = 1 go
在此方案中,应用程序遇到性能问题。注意 有关如何识别此问题的详细信息,请参阅 "详细信息" 部分。
原因
出现此问题的原因是,当查询文本相同时,将相同的查询计划插入到每个用户的相同哈希存储桶中的缓存中。将大量计划散列到同一存储桶(也称为哈希链)时,在缓存中查找计划的时间将显著增加,并且可能会出现性能问题。 此外,工作线程可能会遇到严重的 spinlock 争用,并且当这些工作线程未执行正确的计划程序时,其他线程会受到影响。
解决方案
注意 目前只有 SQL Server 2008 R2 更新可用。 有关 SQL Server 2008,请参阅 "解决方法" 部分以解决此问题。
累积更新信息
SQL Server 2008 R2 Service Pack 1
此问题的修补程序首次在 SQL Server 2008 R2 Service Pack 1 的累积更新1中发布。有关如何获取此累积更新包的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2544793 SQL Server 2008 R2 Service Pack 1 的累积更新包1注意 由于这些版本是累积的,因此每个新的修复版本都包含了以前的 SQL Server 2008 R2 修补程序版本附带的所有修补程序和所有安全修补程序。 我们建议你考虑应用包含此修补程序的最新修复版本。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2567616 在发布 SQL Server 2008 R2 Service Pack 1 之后发布的 SQL Server 2008 R2 版本
SQL Server 2008 R2
此问题的修补程序首次在累积更新7中发布。有关如何为 SQL Server 2008 R2 获取此累积更新包的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2507770 SQL Server 2008 R2 的累积更新包7 注意 由于这些版本是累积的,因此每个新的修复版本都包含了以前的 SQL Server 2008 R2 修补程序版本附带的所有修补程序和所有安全修补程序。 我们建议你考虑应用包含此修补程序的最新修复版本。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
981356 发布 SQL Server 2008 R2 后发布的 SQL Server 2008 R2 版本
状态
Microsoft 已确认这是在“适用范围”部分中列出的 Microsoft 产品存在的问题。
解决方法
若要在 SQL Server 2008 和 SQL Server 2008 R2 中解决此问题,请将临时表的任何引用移到内部存储过程中。
更多信息
有关如何创建和修改表基础知识的详细信息,请访问以下 MSDN 网站:
如何创建和修改表格基础知识Spinlock 争用可通过 sys.dm_os_spinlock_stats 动态管理视图(DMV)识别,该视图在 SOS_CACHESTORE Spinlock 上具有高争用率。若要确定此问题,请运行类似于以下内容的查询:
select cp.bucketid, count(cp.bucketid) as BucketCount, st.text from sys.dm_exec_cached_plans cp cross apply sys.dm_exec_sql_text(cp.plan_handle) as st group by cp.bucketid, st.text having count(cp.bucketid) >1 order by BucketCount desc如果在运行此查询时满足以下条件,则可能会遇到性能问题:
-
此查询将生成相同的查询文本。
-
同一 bucketid 的计数很大。注意 同一 bucketid 的大量计数通常超过1000。
-
查询引用临时表