用友 oa(用友oa办公软件)

金蝶云星空性能提升200倍的实战案例

案例背景:案例公司金蝶云星空出入库单据和相关报表查询一年的数据,20分钟都出不来,优化后全部不到1分钟出来,最大的一只程序,原来执行需要3个小时,优化后不到1分钟,性能提升200倍。

摘要:本文不涉及简单的硬件,网络,操作系统,数据库参数和索引优化等稍微靠谱一点的代理商都会的技术,但完整的分析步骤会提供优化文档和性能检查SQL程序 供下载(售价100元),针对所有曾经的新老同事和新老客户 都可免费找作者获取。

分析思路

1 按优化文档分析现状和可优化环节(本文略)

2 找到耗时最多的程序

3 针对这个程序做分析,作用和功能是什么,以及为什么慢

4 针对性优化



执行分析思路

1 按优化文档分析现状和可优化环节

结果:发现90%的部分,已经有人做了优化,但是并没有作用

2 找到耗时最多的程序

结果:发现有一只程序执行了174分钟,大约耗时三小时,并且每4个小时执行一次,导致所有程序受此拖累,出入库单据查询一年的数据,20分钟都出不来

金蝶云星空性能提升200倍的实战案例

3 针对这个程序做分析,作用和功能是什么,以及为什么慢

下面是优化之前的程序,供参考

                     CREATE PROCEDURE [dbo].[pro_pur_req_innerText]AS     BEGIN        PRINT '-----开始--------'        DECLARE @FBillNo VARCHAR(200)        DECLARE @Fid VARCHAR(200)        DECLARE pur_req_order CURSOR        FOR            ( SELECT DISTINCT                        a.FID ,                        FBillNo              FROM      T_PUR_REQUISITION AS a                        INNER JOIN T_PUR_REQENTRY AS b ON a.FID = b.FID                        INNER JOIN t_bd_material AS c ON b.FMATERIALID = c.FMATERIALID              WHERE     CONVERT(VARCHAR(100), a.FCreateDate, 23) > CONVERT(VARCHAR(100), DATEADD(DAY,                                                              -10, GETDATE()), 23)                        AND ISNULL(b.F_BKK_TEXT, '') = ''                        AND c.FNUMBER LIKE '3%'            )        OPEN pur_req_order        FETCH NEXT FROM pur_req_order INTO @Fid, @FBillNo        WHILE @@FETCH_STATUS = 0             BEGIN                PRINT @FBillNo                UPDATE  A                SET     A.F_BKK_TEXT = d.Fjx                FROM    T_PUR_ReqEntry AS A WITH ( NOLOCK )                        INNER JOIN ( SELECT DISTINCT                                            b.FID ,                                            b.FBILLNO ,                                            d.FBILLNO AS reqbill ,                                            b.FEntryID ,                                            a.FMaterialId ,                                            CONCAT(RIGHT(a.Fmodel,                                                         PATINDEX('%/%',                                                              REVERSE(a.Fmodel)))                                                   + ';' + RIGHT(c.Fmodel,                                                              PATINDEX('%/%',                                                              REVERSE(c.Fmodel))),                                                   ';', a.BCJX) Fjx                                     FROM   ( SELECT    B.FMaterialId ,                                                        A.FBILLNO ,                                                        B.FENTRYID ,                                                        C.FSPECIFICATION fmodel ,                                                        C.FDESCRIPTION ,                                                        D.F_BKK_TEXT BCJX --销售订单的料号规格                                              FROM      T_PLN_FORECAST                                                        AS a                                                        INNER JOIN T_PLN_FORECASTENTRY                                                        AS b ON a.FID = b.FID                                                        INNER JOIN T_BD_MATERIAL_L                                                        AS C ON B.FMaterialId = C.FMaterialId                                                        INNER JOIN T_BD_MATERIAL                                                        AS D ON B.FMATERIALID = D.FMATERIALID                                            ) AS A                                            INNER JOIN ( SELECT                                                              FDEMANDBILLNO ,                                                              A.FID ,                                                              a.fbillno ,                                                              B.FENTRYID ,                                                              C.FDEMANDBILLENTRYID --关联来源单号                                                         FROM T_PUR_Requisition                                                              AS A                                                              INNER JOIN T_PUR_ReqEntry                                                              AS B ON A.FID = B.FID                                                              INNER JOIN T_PUR_ReqEntry_R                                                              AS C ON B.FID = C.FID                                                              AND B.FENTRYID = C.FENTRYID                                                       ) AS B ON a.FBILLNO = b.FDEMANDBILLNO                                                              AND a.FENTRYID = b.FDEMANDBILLENTRYID                                            INNER JOIN T_PUR_Requisition                                            AS d WITH ( NOLOCK ) ON b.FID = d.FID                                                              AND --关联采购申请单                                         CONVERT(VARCHAR(100), d.FCreateDate, 23) > CONVERT(VARCHAR(100), DATEADD(DAY,                                                              -10, GETDATE()), 23)                                            INNER JOIN ( SELECT DISTINCT                                                              a.FParentMaterialId ,                                                              a.FParentNumber ,                                                              b.FNUMBER FCHILDNUMBER ,                                                              b.FSPECIFICATION fmodel --电子表总成                                                         FROM VICBOM                                                              AS a                                                              INNER JOIN VICBOM                                                              AS b ON a.FNUMBER = b.FParentNumber                                                         WHERE                                                              b.Fname LIKE '%电控总成%'                                                       ) AS c ON a.FMaterialId = c.FParentMaterialId                                   ) AS d ON a.FID = d.FID                                             AND a.FEntryID = d.FEntryID                WHERE   d.reqbill = @FBillNo                FETCH NEXT FROM pur_req_order INTO @Fid, @FBillNo            END        CLOSE pur_req_order        DEALLOCATE pur_req_order    ENDGO


结论:

2.1 该程序的功能是更新销售订单来源的采购申请单自定义的机型字段

2.2 机型 =销售订单上产品的 规格型号+ BOM展开两层取 电子表总成和 电控总成 的 规格型号

2.3 只更新最近10天的采购申请单,并且按采购申请单号逐个更新

2.4 背景:该程序为前前前任IT总监所写,写完之后还没有优化就离职了,后面的人一直没有解决此问题,也给当地最大的代理商反馈过,金蝶总部也查了,查出了原因,但没有给出优化办法,后面经过多次交接和岁月的流转,连原因也没人知道了

2.5 通过执行计划和代码整体分析,速度慢主要是

2.5.1 通过游标逐个采购申请单号进行循环

2.5.2 每次都要对所有的BOM进行展开,然后再筛选需要的数据

2.5.3 对很多大表都是先join 后筛选,导致各表串联之后 笛卡尔积 变得非常巨大,影响性能

最终优化方法:

1 原有程序整体架构不行,小修小改无法达到大幅改善性能的效果

2 重写原有程序,将游标循环去除,展BOM程序 独立出去,并且先筛选后展开,大幅降低各表串联笛卡尔积的结果

3 实践测试,新程序可以在不到一分钟内执行完成,性能提升200倍。

金蝶云星空ERP性能优化方法实操指南 和 sql server 数据库查看阻塞,耗费IO,CPU资源的语句分析 源代码

https://mbd.pub/o/bread/ZJaXlptu

温馨提示:曾经的同事和新老客户不要拍,可免费找作者获取


总结:文章中提到的查找性能瓶颈的SQL代码,适用于所有基于sql server的应用程序,包含但不限于金蝶,用友ERP等。

Bitget交易所

Bitget交易所V

金蝶云星空性能提升倍的实战案例案例背景案例公司金蝶云星空出入库单据和相关报表查询一年的数据分钟都出不来优化后全部不到分钟出来最大的一只程序原来执行需要个小时优化后不到分钟性能提升倍摘要本文不涉及简单的硬件网络操作系统数据库参数和索引优化等稍微靠谱一点的代理商都会的技术但完整的分析步骤会提供优化文档和...

文章数
0 评论数
浏览数

最近发表

热门文章

标签列表

目录[+]