我知道这是一个广泛的问题,但我继承了几个表现不佳的人,需要对它们进行严重优化。我想知道优化所涉及的最常见步骤是什么。那么,你们中的一些人在面对同样的情况时会采取什么措施呢?
相关问题:
可以应用哪些通用技术来优化 SQL 查询?
我知道这是一个广泛的问题,但我继承了几个表现不佳的人,需要对它们进行严重优化。我想知道优化所涉及的最常见步骤是什么。那么,你们中的一些人在面对同样的情况时会采取什么措施呢?
相关问题:
可以应用哪些通用技术来优化 SQL 查询?
在 SQL Server 中,您可以在查询分析器或 Management Studio 中查看查询计划。这将告诉您在每批语句中花费的时间的粗略百分比。您需要查找以下内容:
其他一些一般提示:
最后,我强烈建议您创建一组负载测试(使用 Visual Studio 2008 测试版),您可以使用它们来模拟您的应用程序在处理大量请求时的行为。一些 SQL 性能瓶颈仅在这些情况下才会显现出来,并且能够重现它们使得修复起来容易得多。
索引可能是一个很好的起点……
使用SQL Server索引调整向导可以解决这个容易实现的目标。
我不确定其他数据库,但对于 SQL Server,我推荐执行计划。它非常清楚(尽管有很多垂直和水平滚动,除非你有一个 400 英寸的显示器!)显示你的查询的哪些步骤正在消耗时间。
如果你有一个步骤需要疯狂的 80%,那么也许可以添加一个索引,然后在调整索引之后,重新运行执行计划以找到你的下一个最大步骤。
经过几次调整后,您可能会发现确实没有任何步骤可以从其他步骤中脱颖而出,即每个步骤都是 1-2%。如果是这种情况,那么您可能需要查看是否有方法可以减少查询中包含的数据量,是否需要将这 400 万个已关闭的销售订单包含在“活动销售订单”查询中? 不,所以排除所有那些 STATUS='C' ... 或类似的东西。
您将从执行计划中看到的另一个改进是书签查找,基本上它在索引中找到匹配项,但是 SQL Server 必须快速遍历表以找到您想要的记录。此操作有时可能比首先扫描表所花费的时间更长,如果是这种情况,您真的需要该索引吗?
对于索引,特别是对于 SQL Server 2005,您应该查看 INCLUDE 子句,这基本上允许您在索引中拥有一列而不真正在索引中,因此如果您查询所需的所有数据都在您的索引中或是一个包含的列,那么 SQL Server 甚至不必查看表,这是一个很大的性能提升。
您可以查看几件事来优化查询性能。
确保您只有最少的数据。确保仅选择所需的列。将字段大小减少到最小。
考虑对数据库进行反规范化以减少连接
避免循环(即获取游标),坚持设置操作。
将查询实现为存储过程,因为这是预编译的,并且执行速度更快。
Make sure that you have the correct indexes set up. If your database is used mostly for searching then consider more indexes.
Use the execution plan to see how the processing is done. What you want to avoid is a table scan as this is costly.
Make sure that the Auto Statistics is set to on. SQL needs this to help decide the optimal execution. See Mike Gunderloy's great post for more info. Basics of Statistics in SQL Server 2005
Make sure your indexes are not fragmented Reducing SQL Server Index Fragmentation
Make sure your tables are not fragmented. How to Detect Table Fragmentation in SQL Server 2000 and 2005
查看进行查询的表上的索引。参与 where 子句的特定字段可能需要索引。还要查看查询中连接中使用的字段(如果存在连接)。如果索引已经存在,请查看索引的类型。
失败(因为使用锁定提示有负面影响)查看锁定提示并明确命名要在连接中使用的索引。如果您遇到大量死锁事务,则使用 NOLOCKS 会更加明显。
做 roman 和 Andy S 首先提到的。
执行计划是一个很好的开始,它将帮助您确定需要处理的查询部分。
一旦你弄清楚了在哪里,就该解决如何以及为什么了。查看您尝试执行的查询类型。不惜一切代价避免循环,因为它们很慢。不惜一切代价避免使用游标,因为它们很慢。尽可能坚持基于集合的查询。
如果您正在使用连接,有一些方法可以为要使用的连接类型提供 sql 提示。不过这里要小心,虽然一个提示可能会加快您的查询一次,但它可能会在下一次根据数据和参数减慢您的查询 10 倍。
最后,确保您的数据库索引良好。一个好的起点是包含在 where 子句中的任何字段可能应该有一个索引。