CYThor 2023-03-02 22:47 采纳率: 100%
浏览 38
已结题

SQL对后端造成超长运行时间

在我们公司的项目要从前端对数据库进行操作的这个模块中,每一次更改都需要等上超过一分钟的时间,即使改动微小也一样,虽然最后确实可以正确完成更改,但每次都要等待超过一分钟极大影响了用户体验。

本身这个模块并没有报错,功能也能正常完成,现在的问题是要完成一个运行速度上的优化,以下是我经过排查之后造成问题的代码:


merge [CPMApplication].[ForecastIterationRow] as TargetTbl
using(
          select source_table.Level3ID, source_table.Level3ComponentID, source_table.DA1ID,
          source_table.Level3Name, source_table.FiscalPeriod as p, SUM(source_table.Total) as NewDollars
          from [CPMApplication].[v_NonLabourRowsByPeriod] as source_table
          where IterationID = @iteration_id
          Group By source_table.Level3ID, source_table.Level3ComponentID, source_table.DA1ID,
          source_table.Level3Name, source_table.FiscalPeriod
        ) as rowsource
        
        ON TargetTbl.AccountLevel3ID = rowsource.Level3ID and
        TargetTbl.AccountLevel3ComponentID = rowsource.Level3ComponentID and
        TargetTbl.DA1DepartmentID = rowsource.DA1ID and
        TargetTbl.FiscalPeriod = rowsource.p and 
        TargetTbl.IterationID = @iteration_id and
        TargetTbl.BaseFlag = 0
        
        
        when MATCHED  then UPDATE
        set TargetTbl.Amount = rowsource.NewDollars,
        LoadDateTime = GETDATE(),
        Email =@email
        when not matched then
        INSERT (
        IterationID,
        DA1DepartmentID,
        AccountLevel3ID, 
        AccountLevel3ComponentID, 
        FiscalPeriod,
        BaseFlag, 
        Amount, 
        LoadDateTime, 
        ApplicationOrigin, 
        Email
        )
        values (
        @iteration_id,
        rowsource.DA1ID,
        rowsource.Level3ID, 
        rowsource.Level3ComponentID, 
        rowsource.p, 
        0,
        rowsource.NewDollars,
        GETDATE(),
        9,
        @email
        );

由于我是公司的新“前端”员工,不确定随便在“后端”做尝试会对公司的数据库造成多大的影响,这个项目的数据库是有上百万个内容的大型数据库
我初步猜测:造成超长时间等待的原因应该是每次对数据库进行更新的时候,该段代码的前几行都会过一遍整个数据库,造成了运行时间超长。
我想问的是,再不改动数据库本身的情况下,如何通过修改这些代码来优化运行速度?
或许将“遍历整个数据库”改为“单行直接插入”之类的会有效果?
当然我也不确定这么做真的能实现吧

我们在VS code上工作,使用的前端是reactJS,后端是NodeJS,数据库是MySQL,测试网页的浏览器为chrome

  • 写回答

1条回答 默认 最新

  • 社区专家-Monster-XH 2023-03-02 22:53
    关注

    基于Monster 组和GPT的调写:

    SQL查询使用了 MERGE 语句来更新或插入数据到目标表。 MERGE 语句在处理大量数据时可能会变得很慢,因为它需要比较目标表和源表的所有行,然后执行插入、更新或删除操作。所以,这个查询的性能问题可能与 MERGE 语句本身有关。

    以下是一些优化建议,可以尝试将它们应用到您的查询中,以提高其性能:

    • 考虑使用 INSERT 和 UPDATE 语句代替 MERGE 语句,因为 INSERT 和 UPDATE 语句在大多数情况下比 MERGE 语句更快。这是因为 MERGE 语句需要比较两个表的所有行,而 INSERT 和 UPDATE 语句只需操作目标表。
    • 如果需要在源表和目标表之间进行比较,请确保目标表和源表都有适当的索引,以便可以快速查找和比较它们的行。在代码中,目标表应至少有一个包含 IterationID,AccountLevel3ID,AccountLevel3ComponentID,DA1DepartmentID和FiscalPeriod 列的复合索引。
    • 考虑将 ON 子句中的 AND 条件排序,以使最有可能匹配的条件排在最前面。例如,如果 AccountLevel3ID 和 AccountLevel3ComponentID 列是最有可能匹配的列,则可以将这些列的条件放在 ON 子句的开头。
    • 考虑将 v_NonLabourRowsByPeriod 视图中的 IterationID 列的索引添加到您的查询中,以便可以更快地筛选出与给定 IterationID 匹配的行。
    • 检查目标表的约束和触发器是否会影响您的查询的性能。如果可能,请禁用它们,以便查询可以更快地运行。
    • 如果查询中涉及的表太大而无法在合理的时间内查询完全,请考虑将查询拆分为多个较小的查询,然后将结果合并。例如,可以在每个迭代中查询一部分行,然后将这些查询结果合并到一个单独的结果集中。
    • 最后,建议使用查询分析器等工具来分析您的查询,查找慢速操作或查询瓶颈,并尝试应用适当的优化策略。
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 3月11日
  • 已采纳回答 3月3日
  • 创建了问题 3月2日

悬赏问题

  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页
  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信
  • ¥30 Python调用dll文件输出Nan重置dll状态