优化性能不佳的查询应采取哪些步骤?
我知道这是一个广泛的问题,但是我继承了几个性能不佳的产品,因此需要对它们进行优化。我想知道优化涉及的最常见步骤是什么。那么,你们中的一些人在遇到相同情况时会采取什么步骤?
Related Question: What generic techniques can be applied to optimize SQL queries?
解决方案
回答
索引可能是一个很好的起点...
可以用SQL Server索引调整向导将低下的果实击倒。
回答
- 在查询分析器中查看执行计划
- 看看哪个步骤花费最多
- 优化步骤!
- 返回步骤1 [向Vinko致敬]
回答
查看进行查询的表上的索引。参与where子句的特定字段可能需要索引。还要查看查询中的联接中使用的字段(如果存在联接)。如果索引已经存在,请查看索引的类型。
失败(因为使用锁定提示会带来负面影响)查看锁定提示并显式命名要在联接中使用的索引。如果我们遇到很多死锁的事务,那么使用NOLOCKS更为明显。
做罗马和安迪·S首先提到的。
回答
在SQL Server中,我们可以在Query Analyzer或者Management Studio中查看查询计划。这将告诉我们在每批语句中花费的时间的大致百分比。我们将需要查找以下内容:
- 表扫描;这意味着我们完全缺少索引
- 索引扫描;查询可能没有使用正确的索引
- 查询中每个步骤之间的箭头粗细告诉我们该步骤正在产生多少行,非常粗的箭头表示我们正在处理很多行,并且可以指示一些连接需要优化。
其他一些一般性提示:
- 大量的条件语句,例如多个if-else语句,可能会导致SQL Server不断重建查询计划。我们可以使用Profiler进行检查。
- 确保不同的查询不会相互阻塞,例如,更新语句阻塞了select语句。可以通过在SQL Server select语句中指定(nolock)提示来避免这种情况。
- 正如其他人提到的,请尝试使用Management Studio中的"性能调整"向导。
最后,我强烈建议创建一组负载测试(使用Visual Studio 2008测试版),我们可以使用该负载测试来模拟应用程序在处理大量请求时的行为。某些SQL性能瓶颈仅在这种情况下才会显现出来,并且能够重现这些瓶颈使其更容易修复。
回答
执行计划是一个很好的开始,它将弄清楚我们需要解决查询的哪一部分。
一旦确定了位置,就该解决方法和原因了。查看我们要执行的查询的类型。不惜一切代价避免循环,因为它们很慢。不惜一切代价避免游标,因为它们很慢。尽可能坚持设置基于查询的查询。
如果我们正在使用联接,则可以通过多种方法为sql提示要使用的联接类型。不过请注意,尽管一个提示可能会使查询加速一次,但根据数据和参数的不同,下一次查询的速度可能会降低10倍。
最后,确保数据库索引正确。一个很好的起点是where子句中包含的任何字段都可能在其上具有索引。
回答
我不确定其他数据库,但是对于SQL Server,我建议执行计划。它非常清楚地显示(尽管有很多垂直和水平滚动,除非我们有400英寸的监视器!)显示了查询的哪些步骤正在浪费时间。
如果我们迈出了疯狂的80%的一步,那么也许可以添加一个索引,然后对索引进行调整后,重新运行执行计划以查找下一个最大的步骤。
经过几次调整后,我们可能会发现确实没有其他步骤可以脱颖而出,也就是说,每个步骤都只有1-2%。如果是这样,那么我们可能需要查看是否有一种方法可以减少查询中包含的数据量,是否需要在"有效销售订单"查询中包含这四百万个已关闭的销售订单? ?不,所以排除所有STATUS ='C'...或者类似的东西。
我们将从执行计划中看到的另一项改进是书签查找,基本上它可以在索引中找到匹配项,但是SQL Server必须快速遍历表才能找到所需的记录。有时,此操作可能比仅扫描表所花的时间要长,如果是这种情况,我们真的需要该索引吗?
使用索引,尤其是使用SQL Server 2005时,我们应该查看INCLUDE子句,这基本上使我们可以在索引中包含一列而不必真正包含在索引中,因此,如果查询所需的所有数据都在索引或者是包含的columnn,则SQL Server甚至不必查看表,这是一个很大的性能提升。
回答
我们可以考虑以下几项来优化查询性能。
- 确保我们只拥有最少的数据。确保仅选择所需的列。将字段大小减小到最小。
- 考虑对数据库进行非规范化以减少联接
- 避免循环(即获取游标),坚持设置操作。
- 将查询实现为存储过程,因为它是预编译的,并且将更快地执行。
- 确保我们设置了正确的索引。如果数据库主要用于搜索,请考虑使用更多索引。
- 使用执行计划来查看处理过程。我们要避免的是表格扫描,因为这样做成本很高。
- 确保将"自动统计信息"设置为"开"。 SQL需要此来帮助确定最佳执行。有关更多信息,请参见Mike Gunderloy的精彩文章。 SQL Server 2005中的统计基础
- 确保索引没有碎片化减少SQL Server索引碎片
- 确保表没有碎片。如何在SQL Server 2000和2005中检测表碎片