我有一个存储过程当前正在执行一个复杂的提取,该提取在使用时经常超时。我部门提出的解决方案是简单地增加超时时间;我真的不想这样做。我想重构这个存储过程,但是因为它非常复杂且没有文档记录(是的遗留系统),我担心我的重构不会导致相同的功能更有效地执行。在重构存储过程以确保在更短的时间内执行相同的功能时,是否可以使用任何策略?
这是一个 Microsoft SQL Server 2005 存储过程。
我有一个存储过程当前正在执行一个复杂的提取,该提取在使用时经常超时。我部门提出的解决方案是简单地增加超时时间;我真的不想这样做。我想重构这个存储过程,但是因为它非常复杂且没有文档记录(是的遗留系统),我担心我的重构不会导致相同的功能更有效地执行。在重构存储过程以确保在更短的时间内执行相同的功能时,是否可以使用任何策略?
这是一个 Microsoft SQL Server 2005 存储过程。
通常,超时发生在单个 SQL 语句上。可能通过有效利用临时表将 proc 分解为单独的语句,因此您不会尝试在一个块中做太多事情。通过这样做,您还可以磨练您的性能瓶颈,并可能在需要时识别一些有用的索引。
我遇到的存储过程效率低下的最常见原因是标量类型操作的普遍存在,而不是基于集合的操作。大多数 RDBMS 系统(Oracle、SQL Server、MySQL 等)在处理大量数据时效率更高,而不是单个操作重复多次。对一百万行数据执行一次操作比对每一行执行一百万次操作更有效。
在尝试确定这些类型的瓶颈(通常首先查看函数调用)之后,我建议查看您正在引用的表上的索引策略。根据您选择的 RDBMS,您可能拥有一些向导类型的功能,可以帮助您根据示例工作负载发现合适的索引结构。
你用的是什么数据库?这可能有助于微调我的一些建议。
我过去一直面临这种情况。最好的办法是创建一个简单的 C# 或 VB .Net 应用程序。当你重构 sp 时,给它一个新的名字。使用该应用程序来调用旧的和新的 sp。然后比较两个 sp 的输出,以确保它们以相同的顺序返回完全相同的值。
您可能希望测试尽可能多的输入参数,以确保您的重构没有修改业务逻辑。
此外,使用 NUnit 可以帮助简化此任务。
当我开始我现在的职位时,我得到了一个必须为新模式修改的数据库。它需要更改超过 100 个 sp。使用我描述的应用程序,我能够合理地确定我的修改之一没有违反业务规则。
你是对的,只是增加超时是错误的第一个答案。尽可能提高 sp,然后在必要时增加超时。
使用SQL Server Profiler研究当前 SP 是如何运行的;它将突出显示效率低下的地方,并允许您从一开始就针对那些特定领域,同时不理会更高性能的部分。然后,您可以在修改后的 SP 上再次使用分析器来比较性能。
我会赞同 Gunny 的建议,即仔细研究函数调用——在基于集合的操作中,这些会对性能产生真正的影响。过去,我仅通过剥离单个 UDF 并复制内联逻辑就获得了巨大的性能提升。