Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
“重构”;极端的;SQL查询_Sql_Sql Server 2005_Refactoring - Fatal编程技术网

“重构”;极端的;SQL查询

“重构”;极端的;SQL查询,sql,sql-server-2005,refactoring,Sql,Sql Server 2005,Refactoring,我有一位业务用户,他试图为项目统计报告(例如任务数量、里程碑等)编写自己的SQL查询。查询首先声明一个80多列的临时表。然后,temp表中有将近70条UPDATE语句,每一条都包含自己的一小部分业务规则,这些语句包含将近500行代码。它以从临时表中选择*结束 由于时间限制和“其他因素”,这项技术被匆忙投入生产,现在我的团队一直在支持它。性能是令人震惊的,尽管由于一些整理,它相当容易阅读和理解(尽管代码的味道很难闻) 为了加快这一过程并遵循良好实践,我们应该关注哪些关键领域?好吧,因为您告诉我们的

我有一位业务用户,他试图为项目统计报告(例如任务数量、里程碑等)编写自己的SQL查询。查询首先声明一个80多列的临时表。然后,temp表中有将近70条UPDATE语句,每一条都包含自己的一小部分业务规则,这些语句包含将近500行代码。它以从临时表中选择*结束

由于时间限制和“其他因素”,这项技术被匆忙投入生产,现在我的团队一直在支持它。性能是令人震惊的,尽管由于一些整理,它相当容易阅读和理解(尽管代码的味道很难闻)


为了加快这一过程并遵循良好实践,我们应该关注哪些关键领域?

好吧,因为您告诉我们的关于此存储过程的唯一一件事是它有一个80多个列的临时表,所以我唯一建议的是删除该表,然后重写其余部分以消除对它的需要。

您应该获得一个工具,该工具允许您获得应用程序将运行的所有查询的解释计划。这是提高SQL应用程序性能的最佳选择。如果你阅读并对解释计划告诉你的内容做出反应。如果你在甲骨文上,我们以前用的是Qwest的蟾蜍(?)我想。这是一个很棒的工具。

我要做的第一件事是检查以确保定期运行活动索引维护作业。如果没有,则重建所有现有索引,如果不可能,则至少更新统计信息

我要做的第二件事是设置一个跟踪(如上所述),并找出哪些语句导致了最高的读取次数

然后,我将在SSMS中运行“显示实际执行计划”,并将结果与跟踪结果相吻合。由此,您应该能够确定是否缺少可以提高性能的索引


编辑:如果你要投否决票,请留下评论,说明原因

如果这是一个生成报表的存储过程,它多长时间运行一次?如果一天只需要运行一次,并且在夜间运行,那么性能会有多大问题

如果不是这样的话,我建议你在选择重写时要小心,因为你有可能会弄糟你的数据

另外,它听起来像是应该被拉到SSIS包中的一种东西,用结果构建一个新的永久表,这样它只需要运行一次


希望这是有意义的

我建议查看相关的表、最终结果,然后从头开始,看看是否可以以更高效的方式完成查询。保留查询以验证新查询是否与旧查询完全相同,但请尝试忘记用于获取最终结果的所有方法

就像任何重构一样,确保在每次更改后都有一种自动化的方法来验证重构(您可以使用查询来根据已知的良好基线检查开发输出),然后自己编写。这样,您总是在匹配已知的良好数据。当您进入决定是否切换到流程的新版本并希望并排运行几个迭代以确保正确性的阶段时,这将使您对方法的正确性有高度的信心


我还喜欢记录所有测试批和批中进程的运行时间,这样我就可以知道批中的某些特定进程是否在某个时间点受到了不利影响。我可以获得流程的平均时间,并查看改进趋势或发现潜在问题。这也让我能够识别批次中最容易改进的地方。

我会从头重写它


你说你明白它应该做什么,所以不应该那么困难。我敢打赌,这段代码的需求将不断变化,因此如果您现在不重写它,您可能最终会维护一些丑陋的怪物,您可以尝试的一件事是用一个表变量替换temp表。有些时候,这是更快的,有些时候不是,你只能试试看

请看70条update语句。有可能将它们中的任何一个结合起来吗?如果作者没有使用案例陈述,可能会少做陈述


其他显而易见的事情需要注意-删除任何游标,将任何子查询更改为表或派生表的联接。

首先,如果这不会导致业务问题,则将其保留,直到问题出现为止。等到它成为一个问题,然后修复一切

当您决定修复它时,请检查是否有一条语句导致您的大多数速度问题。。。把它拆开并修好

如果所有语句都存在速度问题,并且您可以将所有语句合并到一个SELECT中,这可能会节省您的时间。我曾经将一个类似这样的程序(没有那么多的更新)转换为一个SELECT,运行它的时间从超过3分钟变为不到3秒(没有狗屎…我简直不敢相信)。顺便说一下,如果某些数据来自链接服务器,请不要尝试此操作

如果出于任何原因,您不想或不能这样做,那么您可能需要调整现有的进程。以下是我要看的一些东西:

  • 如果要在临时表上创建索引,请等到首次插入之后再填充它

  • 调整初始插入以插入尽可能多的列。这样做可能会消除一些更新

  • 在运行更新之前为临时表编制索引。在更新语句之前,不要在update语句所针对的任何列上创建索引

  • 如果表和分组允许,请将更新分组。70个更新对于80个栏目来说是相当多的,听起来像是这样