什么是最好的SQL Server性能优化技术?

时间:2008-09-19 16:23:32

标签: sql-server optimization

我一直采用首先使用最少的索引集部署数据库,然后根据性能要求添加/更改索引的方法。

这种方法运作得相当好。但是,它仍然没有告诉我在哪里可以提高性能。它只告诉我性能如此糟糕以至于用户抱怨它。

目前,我正在为许多应用程序重构数据库对象。

因此,我不应该费心寻求性能提升,因为“过早优化是所有邪恶的根源”吗?

在重构应用程序代码时,开发人员一直在寻找提高代码质量的方法。有没有办法不断寻求数据库性能的改进?如果是这样,您发现哪些工具和技术最有帮助?

我简要介绍了“数据库引擎优化顾问”,但没有发现它有用。也许我只需要更多的经验来解释结果。

13 个答案:

答案 0 :(得分:11)

我的方法是使用SQL Server Profiler将针对服务器或数据库的命令收集到表中。完成后,您可以根据max和avg执行时间,max和avg cpu时间以及(也非常重要)查询运行的次数进行查询。

由于我尝试将所有数据库访问代码放在存储过程中,因此我很容易打破查询。如果使用内联SQL可能会更难,因为更改查询中的值会使其看起来像一个不同的查询。您可以尝试使用LIKE运算符解决此问题,将相同类型的查询放入相同的存储区中以计算聚合(max,avg,count)。

一旦你有一个潜在问题的“前10名”列表,你可以开始单独查看它们,看看是否可以重新编写查询,索引可能有所帮助,或者是否需要进行次要的架构更改。要想获得前10名,请尝试以不同的方式查看数据:avg *计算期间的总成本,最坏的罪犯,平均平均等等。

最后,请务必在必要时监控不同的时间段。每个人进入和运行他们的每日报告时的数据库使用情况可能与用户输入新数据时的中午不同。您也可以决定,即使某个夜间进程比其他任何查询都要花费更长时间,因此无关紧要,因为它在非工作时间运行。

祝你好运!

答案 1 :(得分:11)

“过早优化是所有邪恶的根源”

就数据库编程而言,我认为这句话是无稽之谈。重写整个应用程序是非常昂贵的,因为开发人员并不关心第一次编写有效的代码。所有t-sql代码都应该考虑它将如何影响数据库性能(数据完整性当然是第一个)。除了数据完整性之外,性能应该胜过一切。

是的,在遇到问题之前,您应该做一些优化事项,但有些事情应该是理所当然的事情,以后不再修复。编写具有更高效率的代码的代码不会花费更多的时间,一旦您了解了如何通过错误的代码影响效率,就不会有这样的代码。 Cervo对游标代码的讨论就是一个例子。基于集合的操作几乎总是比游标解决方案快得多,因此在基于集合的解决方案时,不应该首先编写游标。它几乎总是花费我更少的时间来编写一个基于集合的解决方案来编写游标,但获得这种方式的唯一方法是永远不要编写游标。

并且没有理由使用select *而不是指定您的字段名称。在MSSQL中,您可以将这些名称从对象资源管理器中拖出来,这样您就无法告诉我这样做太难了。但是,通过仅指定实际需要的字段,可以节省网络资源和数据库服务器资源以及Web服务器资源。那么为什么程序员应该选择*的懒惰选项并担心以后的优化呢?

与索引相同。你说你做了一组最小的索引。根据你如何定义minimal,这可能没问题,但是在所有外键上都有索引是至关重要的,我不想推送一个没有索引的数据库,这些数据通常位于最常见的几个字段中条款。如果您的用户不在内部而非内部,他们不会抱怨您的网站有多慢,他们会去其他地方。从一开始就计划有效的数据库访问只会使总线感觉良好。

我从一开始就未能考虑效率的主要担忧之一是,事情太慢的公司往往只会在问题上投入更多设备而不是性能调整。当人们开始进行性能调整时,你就拥有了几千兆字节或更多的数据库,其中许多不满意的客户获得超时而不是结果。此时,通常几乎所有数据库中的内容都必须重写,与此同时,您正在失去客户。我记得在一家拥有商业应用程序的公司提供支持时,客户服务代表需要花费十分钟时间从一个屏幕移动到另一个屏幕,同时他们试图通过电话帮助已经心怀不满的客户。您可以想象,由于我们无法更改的商业产品中设计不良的数据库查询,公司丢失了多少客户。

答案 2 :(得分:5)

答案 3 :(得分:2)

配置完成后,将您认为麻烦的查询放入SQL查询分析器并显示执行计划。确定执行昂贵的表扫描的部分查询,并重新索引这些表以最大限度地降低此成本。

试试这些参考资料:

Optimizing SQL
How to Optimize Queries

答案 4 :(得分:1)

分析您的查询,而不是明显的查询,但访问不同的表,视图等的复杂和/或从不同的表返回多行的查询

这会告诉你应该关注的确切位置

答案 5 :(得分:1)

分析是关键,但在使用分析集时,您必须确保它是一个准确的数据测试集,否则调优工具将无法为您提供所需的准确结果。

2005年使用碎片的管理对象也非常有用!

答案 6 :(得分:1)

当然,您必须分析您的查询并查看执行计划。但是,一次又一次出现的两个主要问题是尽快过滤掉并尝试避免使用游标。

我看到一个应用程序,其中有人将一个完整的事件数据库表下载到客户端,然后根据某些条件逐个过滤每一行。将过滤条件传递给数据库并使查询在where子句中应用条件时,性能会有很大提高。这对于使用数据库的人来说是显而易见的,但我已经看到了类似的事情。还有一些人的查询存储了一堆他们不需要的临时表,然后在临时表的最终连接中将其删除。基本上,如果您从填充临时表的查询中消除,那么查询的其余部分的数据就会减少,整个查询运行得更快。

游标很明显。如果你有一百万行并且逐行,那么它将需要永远。做一些测试,如果你使用像Perl这样的“慢”动态语言连接数据库并对数据集执行一些逐行操作,速度仍然会比数据库中的游标大得多。用Java / C / C ++之类的东西来做,速度差异更大。如果您可以在数据库代码中找到/消除游标,它将运行得更快......如果您必须使用游标,用任何编程语言重写该部分并将其从数据库中取出可能会产生巨大的性能提升。 / p>

关于游标的另一个注意事项,要注意像SELECT @ col1 = col1,@ col2 = col2,@ col3 = col3这样的代码,其中id = @currentid在循环中经过ID然后在每列上执行语句。基本上这也是一个游标。不仅如此,使用真实游标通常比这更快,尤其是静态和forward_only。如果你可以改变基于它设置的操作,那将会快得多.....那就是说,游标有一些地方可以用于某些事情......但是从性能的角度来看,使用基于集合的设置是有惩罚的。方法

还要注意执行计划。有时它估计需要花费几秒钟的操作非常昂贵,并且操作需要花费几分钟才能非常便宜。在查看执行计划时,请确保通过在代码中插入一些SELECT“在此区域”,GETDATE()来检查所有内容。

答案 7 :(得分:1)

我的建议是,在这种情况下,“过早优化是所有邪恶的根源”是荒谬的废话。

在我看来,它完全与设计有关 - 当你设计你的数据模式时,你需要考虑并发性,热点,索引,扩展和使用模式。

如果您不知道需要哪些索引以及如何在不进行分析的情况下立即配置它们,那么您已经失败了。

有数百万种优化查询执行的方法,这些方法都很好,但最终数据落在你告诉它的地方。

答案 8 :(得分:0)

您似乎在谈论MS SQL。

启动探查器并记录您在数据库上运行的最常见查询。 然后在启用执行计划的情况下运行这些查询,您将看到什么(如果有的话)减慢了您的查询速度。然后,您可以继续优化查询或在字段上添加更多索引。

SQL Books将为您提供有关分析和查询分析功能的完整概述。

答案 9 :(得分:0)

您可能希望检查当前索引的内部和外部碎片,然后删除并重新创建它们或重新组织它们。

答案 10 :(得分:0)

确保使用生产量进行分析 - 按行数加载。在不同的负载/容量情况下,查询及其计划的行为会有所不同

答案 11 :(得分:0)

一般来说,这里的提示是:

http://www.sql-server-performance.com/

过去质量很高,对我有用。

答案 12 :(得分:-1)

我的建议是从适用于所有数据库的技术开始,然后尝试特定于MsSQL的技术。

优化SQL很困难,并且没有严格的规则。您可以遵循的通用指南很少,例如:

  • 95%的性能改进将来自应用程序,而不是来自服务器或数据库引擎配置。
  • 首先设计正确性,稍后调整性能
  • 减少数据库的访问
  • 尝试以适合您数据模型的方式表达事物
  • 忽略有关性能的一般性建议 - 是的,在某些时候,您会找到一个系统或SQL语句,其中一个规则不适用。

但关键是你应该始终应用80-20规则。这意味着在任何系统中,您需要调整20%(通常更少)的代码以获得最大的性能提升。这就是供应商提供工具usually fail的地方,因为他们通常无法猜测执行的应用程序/业务上下文。