如何提高MS SQL Server中原始查询的性能?


10

我有一个ASP.NET网站,它拥有自己的独立数据缓存,并且数据不会长时间更改,因此它不需要使用相同的查询第二次查询SQL Server。我需要提高转到该SQL Server的首次(原始)查询的性能。一些查询处理的数据太多,可能导致SQL Server使用tempdb。我不使用临时表变量或临时表,因此SQL Server决定tempdb在需要时自行使用。

我的数据库大小为16Gb,服务器计算机上有32Gb的物理RAM。

我了解MS SQL Server缓存策略会尝试将数据保留在RAM中,以加快类似查询的性能(如果它们需要再次加载相同的数据)。除此之外,它将尝试使用可用的RAM代替tempdb来提高性能,而不会引起磁盘访问。

我想当需要在tempdb SQL Server中存储一些内容的查询出现并且没有足够的RAM可用时,SQL Server有2个选择:

1)卸载一些缓存的数据并使用备用的RAM代替tempdb以避免磁盘写入

2)保留缓存的数据以备将来查询,并开始使用tempdb,这会导致写入慢速磁盘。

我不知道在这种情况下SQL Server会做出什么选择,但我希望它成为选择#1,因为我只关心首次查询(原始)的性能,因为我再也不会向SQL Server发送相同的查询了。 (尽管我可能会发送类似的查询)。

在这种情况下,SQL Server缓存策略是什么?

在避免针对原始查询的tempdb和第二次查询的速度之间,如何平衡RAM的使用?

是否可以以选择#1的方式配置SQL Server?如果是,那怎么办?

我还能如何提高所有原始SQL查询的性能?

由于我不了解SQL Server缓存策略,因此我想将数据库放在RAM磁盘上。这将确保即使SQL Server始终选择#1,任何原始查询都可以高速加载未缓存的数据。这样做的风险是,如果SQL Server继续选择#2,则可能会开始使用更多具有较少可用RAM的tempdb(在我将16Gb用于RAM磁盘后仅剩下16Gb),这将减慢那些导致溢出的原始查询的速度tempdb

我对SQL 2008 R2的解决方案感兴趣,但是我想对于SQL 2008,SQL 2005可能是相同的,并且可能是SQL 2000。

说明:

该框上没有其他应用程序在运行,它专用于SQL Server。网站在单独的框中运行。

它是Windows Server 2008 R2 Enterprise 64位上的SQL Server 2008 R2 Standard Edition 64位。

我只运行只读查询,并且数据库设置为只读

假设已经有好的索引。这个问题是关于SQL Server选择#1与选择#2,如何实现,是否有控制方法以及RAM Disk是否可以帮助它为原始查询做出正确选择的问题。


是什么让您认为即使没有创建临时表也正在使用tempdb?您使用的是非重复表格还是分组表格?
达林海峡

3
32/64位?物理还是虚拟的?该服务器专用于SQL Server,还是在同一盒子上运行IIS或其他应用程序?您是否对查询执行计划进行了分析?您可以发布示例查询和/或执行计划吗?还有一点好运... 在问题查询运行时,按照Kendra的指南记录sp_whoisactive并发布输出。
Mark Storey-Smith

@darinstrait最可能的解释是排序或哈希溢出。
Mark Storey-Smith

Answers:


7

您的问题基本上可以表述为“查询内存授予是如何工作的?”。关于该主题的一本好书是《了解SQL Server内存授予》。在启动查询执行之前,可能需要为排序和散列以及其他占用内存的操作分配内存。此内存授权是一个估计。根据当前系统状态(正在运行和正在处理的请求数,可用内存等),系统会向查询授予不超过所需数量的内存授予。授予内存后,查询将开始执行(它可能必须在可怕的“资源信号量”队列中等待才能获得授权)。在执行时,保证了内存授予通过系统。可以与数据页共享此内存量(因为它们始终可以刷新到磁盘),而不能与其他内存使用量共享(即,它不能被“窃取”)。因此,当查询开始从其授权中请求已提交的内存时,引擎将部署您所谓的“策略1”:数据页可能会被驱逐(如果脏了,则被清除),以便为查询提供所承诺的内存。现在,如果估计是正确的,并且授权是请求的内存的100%,则查询不应“溢出”。但是,如果估算值不正确(归结为基数估算值,因此受制于过时的统计数据),或者如果查询未获得其所要求的全部授权,查询将“溢出”。这是tempdb出现的时候,性能通常会下降。

在此过程中,您可以控制的唯一旋钮是资源调控器。由于RG可用于为池指定MIN设置,因此它可用于为特定工作负载保留内存,以便它实际获得其请求的内存授权。当然,在进行了适当的调查后,可以发现减少的内存授予罪魁祸首,当然,在评估了对其他工作负载的影响之后。和测试,当然。

现在让我们回到您的原始问题。如果您的调查是正确的(如果很大),我想指出两个问题:

  • 您在需要对网站进行内存分配的生产查询中运行。这是一个很大的禁忌。内存授予指示分析查询,该查询在服务HTTP请求中没有位置。
  • 您的查询可能不是获得他们请求的内存授予的事件。同样,对于延迟至关重要的工作负载,与网站一样,它甚至更多。

因此,这告诉我您有一个基本的设计和体系结构问题。网站是由延迟驱动的,应该创建类似OLTP的工作负载,没有内存授予,也没有查询内存压力。更不用说没有泄漏了。分析查询应在脱机作业中运行,并存储预处理结果,以便在HTTP请求需要它们时快速提供可用性。


@Mark:大多数查询不需要内存授予。只有少数运算符(最著名的是sort和hash join)需要工作缓冲区,因此需要授予权限。这是标准的“术语”。您可能正在考虑执行环境和查询执行计划,其中每个查询都需要一个查询,并且其中包含一些内存。内存授予量更大(MB)。其次,看一下sys.dm_exec_query_memory_grants:您有requested(最大值),required(最小值)和granted(实际值)。
Remus Rusanu

道歉。我是从某个查询中获取的最小值是从同一个内存业务员那里分配的,这是不正确的。
Mark Storey-Smith'5

仍然不确定我是否同意你的两个要点。各种琐碎的排序和哈希联接操作都需要在最低级别进行授予,因此建议必须完全消除它们似乎是多余的。授予不足会导致tempdb溢出,这是一个危险信号,这当然是合理的,但是对任何需要授予许可的操作进行全面禁止可能会使许多人走上不必要的抢先优化路径吗?
Mark Storey-Smith

OP声称它具有所有必要的索引。如果这是真的,并且工作负载具有足够大的内存授予(甚至溢出)问题,而且很明显,那么我会说工作负载对于网站而言过于分析。最终,性能优化始终是确定根本原因的调查游戏。所有掩盖性的声明和禁令总是在进行中,找到一个反例证明其错误,这是给定的。OP是否存在设计问题,从而导致分析工作量过大?我不知道。我认为呢?我会说87.5%的信心是。
Remus Rusanu

@Remus:您的猜测很好,我的网站查询是100%可分析的。它允许用户在UI中构造任何可能的查询,以将过滤器,聚合和分组的任何可能组合发送到SQL Server(当然,这会使索引编制变得困难)。是的,我可以让它们以异步模式运行,以保存结果供以后检索,但目标是使任何查询运行得如此之快,以至于2-10秒后立即可以得到结果,而且分析查询是该网站的唯一功能,我认为只有在存在其他非分析查询时,使它们异步才有意义。
羊驼

3

您没有提到的是针对数据库运行的查询类型,以及是否存在正确的索引以加快查询性能。

您还需要确保同一框上是否还有其他应用程序在运行。即使包装盒具有32 GB的RAM,您是否还要在数据库服务器上设置任何最大内存设置以设置任何人为限制。如果在同一服务器上运行有应用程序,则SQL和其他应用程序可能会争用资源,请注意SQL占用大量内存。

SQL Server将使用tempdb进行内部排序或哈希联接/聚合或假脱机运算符等,您将无法控制此行为。您可以做的是限制返回的数据量。

您是否已选中此框上的等待统计信息?每次SQL Server等待资源时,SQL Server都会跟踪等待资源并查看该信息会有帮助。

查看Glenn Berry诊断查询,这对您来说将是一个好的开始。

另请参阅http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspx中提到的PARAMETERIZATION FORCED


好的,我们假设已经有正确的索引。我忘了提到这是具有只读查询的只读数据库,并且SQl Server框上没有其他应用程序在运行。
羊驼

您的统计信息是最新的吗?如果只读数据库丢失或过时,则无法创建统计信息。您的数据是否偏斜或密钥具有唯一值。有很多因素可以导致此行为。
桑卡尔·雷迪

您所说的“这种行为”是什么意思?我没有提到有什么问题。我只想在特殊情况下提高性能。SQL Server已针对在任何情况下运行进行了优化,但在我的情况下它可能无法运行最佳方法。我不确定我是否可以相信SQL Server做出平衡选择#1 vs#2。每次在上面放新数据时,我都会运行sp_updatestats。
羊驼


2
运行sp_updatestats时,选择的采样率是多少。默认比率是非常示例,并取决于索引的大小。如果您的查询主要(仅)查询新数据,即使您执行sp_updatestats,SQL Server也无法对执行计划做出决定。
桑卡尔·雷迪

2

当前,此问题读为解决问题的解决方案。您已经确定RAM磁盘是解决方案,并且您希望有人验证该选择。抱歉,不会发生。

如果您已测量并观察到tempdb溢出,则几乎可以肯定是由于排序或哈希操作以及查询内存授予不足。取决于要处理的数据量,这可能是不可避免的,但是可以提高查询和/或索引编制以避免的可能性。

请看一下“ 缓冲区管理”以更好地了解SQL Server如何管理内存,以及为一些基本工具和DMV查询解释的SQL Server内存管理以了解您的内存分配位置。

我还能如何提高所有原始SQL查询的性能?

这是一个大话题。发布查询和计划,您将获得有针对性的反馈。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.