电脑桌面
添加蚂蚁七词文库到电脑桌面
安装后可以在桌面快捷访问

金蝶云星空 金蝶云·星空性能分析和优化.pdf

金蝶云星空 金蝶云·星空性能分析和优化.pdf_第1页
1/213
金蝶云星空 金蝶云·星空性能分析和优化.pdf_第2页
2/213
金蝶云星空 金蝶云·星空性能分析和优化.pdf_第3页
3/213
崔智刚金蝶云星空性能分析和优化20242课程简介:本课程介绍金蝶云星空产品在使用过程中碰到性能问题时,性能问题的表现,优化的手段,方法以及一些已知的最佳实践。课程说明3课程目标/收益目标•提高分析问题的能力•了解影响性能的方方面面,以及相关的一些知识•提高解决问题的能力收益•降低分析性能问题的周期•碰到问题时,不再束手无策•提高性能优化方面的知识概论可用空间不足高CPU高内存系统崩溃阻塞/死锁低效语句网络课程目录大家碰到性能问题时都会问什么,看什么?问题发生的时间,频率,有无规律,个别现象还是整体现象…网络/应用服务器/数据库服务器…互动6第一章概论7背景知识部署图检查项问题表象服务器表现目录8背景知识性能优化SQL语法数据库原理网络基本知识执行计划操作系统开发语言金蝶云星空架构9部署图金蝶云星空应用服务器操作系统Windows服务IIS.NETframeworkK3CloudJobProcessK3CloudManagerK3CloudMQServiceK3CloudTomcat数据库服务器操作系统WindowsLinux服务OracleSQLServer10检查项操作系统版本/CPU/内存/磁盘IO/网络/日志/参数配置IIS版本/设置/日志.NETFramework版本/配置数据库版本/阻塞/死锁/长时间SQL…金蝶云星空服务版本/配置文件/日志了解版本非常重要11功能卡顿前端报错响应时间非常长前端闪退无法登录…问题表象12服务器表现可用空间不足网络不稳定高CPU高内存高IO低效SQL阻塞死锁崩溃13第二章可用空间不足14平常都碰到过哪些由于空间不足引起系统使用异常的问题?互动15磁盘可用空间不足应用服务器数据库服务器数据库文件空间分配不足目录16系统使用卡顿服务器资源使用不高(原因?)站点无法访问数据库服务器资源使用不高服务器操作卡慢前端提示表空间不够前端提示文件组Primary中的磁盘空间不足…问题表现17IIS日志金蝶云星空服务器日志管理中心\业务站点\文件服务器应用服务器Kingdee\K3Cloud\WebSite\App_Data\LogKingdee\K3Cloud\ManageSite\App_Data\LogKingdee\K3Cloud\Services\ManagementService\LogKingdee\K3Cloud\FileService\TempfilePathKingdee\K3Cloud\FileService\UploadFilesKingdee\K3Cloud\WebSite\TempfilePath18SQLServerTEMPDB文件膨胀数据库故障还原模型为完全严重问题采用默认安装时的路径系统盘数据库服务器19磁盘可用空间不足小结日志文件不要放在系统盘开启日志后,需要定期维护日志数据库安装在非系统盘持续监控磁盘的可用空间20限制了文件最大大小数据库文件空间分配不足21获取文件所在位置设置到新的路径重启SQLServer服务,并删除原来的文件移动TEMPDBSELECTname,physical_nameFROMsys.master_filesWHEREdatabase_id=DB_ID('tempdb');usemastergoAlterdatabasetempdbmodifyfile(name=tempdev,filename='E:\Sqldata\tempdb.mdf')goAlterdatabasetempdbmodifyfile(name=templog,filename='E:\Sqldata\templog.ldf')22大数据量计算的功能成本计算/出入库核算/MRP计算/复杂报表计算/金蝶云星空版本升级原因大量的insert/update/delete操作,导致分配大量空间,引起碎片和高水位使用临时表并存储海量数据,导致临时表空间快速增长使用物理临时表并不及时删除,导致空间快速增长长时间事务,产生大量的事务日志,引起日志快速增长导致数据库空间膨胀的因素23需要了解的几个知识临时表/表变量/版本管理存放位置Tempdb和临时表空间碎片大量数据删除和插入和修改事务日志长时间执行的insert/update/delete语句如何检查呢?24构建大量数据的表,查看表/数据库/tempdb/膨胀问题将数据库的故障还原模型设置为简单后的情况示例25DBCCSHOWCONTIG如何检查或者select*fromsys.dm_db_index_physical_stats(db_id(),object_id('t1'),NULL,null,'detailed')26SQLServerDbccdbreindex注意:表必须有聚集索引优化方法27数据库文件不要放在系统盘如果TEMPDB在系统盘,移动到独立的磁盘SQLServer不做事务日志备份的话,将故障还原模型设置为简单定期监控数据库文件的可用空间定期对数据库进行优化数据库空间分配后,不会自动收缩(同时也不要频繁做收缩或者开启自动收缩)避免大事务导致日志膨胀问题本章小结28第三章高CPU29当CPU高的时候,会看什么?引起CPU高的原因都有什么?互动30SQL语句引起的高CPU代码引起的高CPU防火墙引发的高CPU内核时间目录31数据库开启并行SQL语句关联了大量的表表缺少有效索引SQL语句缺少有效的数据过滤条件HASH关联SQL语句引起的高CPU32两个开关setstatisticstimeonsetstatisticsioon预估和实际执行计划查看方法准备知识33根据SQLServer引擎对SQL语句分配CPU的数目,会带来CPU资源的猛增从而导致高CPU几个等待事件CXCONSUMERCXPACKETSOS_SCHEDULER_YIELD需要关闭数据库开启最大并行度34并行计划并行虽然耗CPU,但某些场景下针对性的开启,是可以的前提是做好充分的验证35非并行:1分22秒并行:41秒并行计划36并行计划一个SPID出现多条记录,并且等待类型为CXPACKET37SQL解析性能非常低下,源于计划的解析方式Join表100多个,SQL解析时间>60SJOIN表太多select...,v1.fname,v1.fnumber,v1.fcoce,...fromtjoint1on...leftjoint2v1on...leftjoint2v2on...leftjoint2v3on...leftjoin…select...,(SELECTT2.fnameFROMT2WHERE...),(SELECTT2.fnumberFROMT2WHERE...),(SELECTT2.fcoceFROMT2WHERE...),...fromtjoint1on...leftjoin...将T2的集合单独获取后,缓存,SQL语句只获取KEY值,然后在前端进行数据合并显示。具体情况具体分析38select*fromt1wherename='T1’createindexidx_nameont1(name)常见场景二开单据,主从表关联字段不建立索引,物料等基础资料字段没有建立索引表缺少有效索引39常见场景列表查询没有过滤条件报表查询日期范围跨年SQL语句缺少有效的数据过滤条件40HASH比Merge成本高32%,将近一倍开销HASH关联41估计的CPU开销将近10倍基于关联操作CPU成本对比42对每行必须生成HAHSKEYHASH运算耗用CPU资源,类似GETHASH()并且花费内存原因43DECLARE@ts_nowbigint=(SELECTcpu_ticks/(cpu_ticks/ms_ticks)FROMsys.dm_os_sys_infoWITH(NOLOCK));SELECTTOP(256)SQLProcessUtilizationAS[SQLServerProcessCPUUtilization],SystemIdleAS[SystemIdleProcess],100-SystemIdle-SQLProcessUtilizationAS[OtherProcessCPUUtilization],DATEADD(ms,-1*(@ts_now-[timestamp]),GETDATE())AS[EventTime]FROM(SELECTrecord.value('(./Record/@id)[1]','int')ASrecord_id,record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]','int')AS[SystemIdle],record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]','int')AS[SQLProcessUtilization],[timestamp]aFROM(SELECT[timestamp],CONVERT(xml,record)AS[record]FROMsys.dm_os_ring_buffersWITH(NOLOCK)WHEREring_buffer_type=N'RING_BUFFER_SCHEDULER_MONITOR'ANDrecordLIKEN'%<SystemHealth>%')ASx)ASyORDERBYrecord_idDESCOPTION(RECOMPILE);获取CPU的历史使用率44SELECTTOP(10)DB_NAME(t.[dbid])AS[DatabaseName],LEFT(t.[text],50)AS[ShortQueryText],qs.total_worker_timeAS[TotalWorkerTime],qs.min_worker_timeAS[MinWorkerTime],qs.total_worker_time/qs.execution_countAS[AvgWorkerTime],qs.max_worker_timeAS[MaxWorkerTime],qs.min_elapsed_timeAS[MinElapsedTime],qs.total_elapsed_time/qs.execution_countAS[AvgElapsedTime],qs.max_elapsed_timeAS[MaxElapsedTime],qs.min_logical_readsAS[MinLogicalReads],qs.total_logical_reads/qs.execution_countAS[AvgLogicalReads],qs.max_logical_readsAS[MaxLogicalReads],qs.execution_countAS[ExecutionCount],qs.creation_timeAS[CreationTime],t.[text]AS[QueryText],qp.query_planAS[QueryPlan]--uncommentoutthesecolumnsifnotcopyingresultstoExcelFROMsys.dm_exec_query_statsASqsWITH(NOLOCK)CROSSAPPLYsys.dm_exec_sql_text(sql_handle)AStCROSSAPPLYsys.dm_exec_query_plan(plan_handle)ASqpORDERBYqs.total_worker_timeDESCOPTION(RECOMPILE);获取最耗CPU的语句45SQL语句越简单越好,尽量避免复杂SQL缺少索引导致大量的IO,如果存储吞吐量存在瓶颈,那么会带来CPU资源增加扫描表的数据范围过大,IO瓶颈引起的高CPU表间关联,HASH操作导致高CPU建议关闭CPU最大并行度所以,数据的范围,实际为IO,直接或者间接导致CPU高小结46循环并发字典锁Linq查询静态/共用字典对象序列化Python表达式编码引起的高CPU47部分CPU或者所有CPU持续在高位表现48内存镜像调试工具WindbgILSpy准备知识49!trheadpool!runaway!clrstack!syncblk!do!objsize!mdt!savemoduleWindbg命令500:100>!threadpoolCPUutilization:100%WorkerThread:Total:33Running:24Idle:8MaxLimit:32767MinLimit:8循环51OSThreadId:0x540(70)ChildSPIPCallSite0000003a8fc2eb3800007ff936b1079a[HijackFrame:0000003a8fc2eb38]0000003a8fc2ebf000007ff92bc89b5dSystem.Collections.Generic.List`1[[System.__Canon,mscorlib]].Contains(System.__Canon)0000003a8fc2ec5000007ff8d3a4ad9dKingdee.K3.MFG.PLN.App.MrpModel.LowestBomCodeImpl.NestingCheckDetailAction.CreateNesttingTreeAction.GetParentRowId(Kingdee.BOS.Orm.DataEntity.DynamicObject,System.Collections.Generic.Dictionary`2>)0000003a8fc2ece000007ff8d3a4a593Kingdee.K3.MFG.PLN.App.MrpModel.LowestBomCodeImpl.NestingCheckDetailAction.CreateNesttingTreeAction.CreateNesttingTree(Int64,Int32,System.Collections.Generic.Dictionary`2>,System.Collections.Generic.Dictionary`2>,System.Collections.Generic.Dictionary`2>)堆栈520:049>!do0000003d09a51ad8Name:System.Collections.Generic.Dictionary`2[[System.String,mscorlib],[System.Collections.Generic.List`1[[Kingdee.BOS.Orm.DataEntity.DynamicObject,Kingdee.BOS.DataEntity]],mscorlib]]MethodTable:00007ff8d1e901a8EEClass:00007ff92b865c10Size:80(0x50)bytesFile:C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dllFields:MTFieldOffsetTypeVTAttrValueName00007ff92b6f853840018878System.Int32[]0instance0000003f26c4dba0buckets00007ff92c942640400188810...non,mscorlib]][]0instance0000003f26c713e0entries00007ff92b6f85a0400188938System.Int321instance32921count00007ff92b6f85a0400188a3cSystem.Int321instance32921version列表对象数32921访问的对象53两层循环外部循环超过3W次内部循环大于100次代码540:055>!threadpoolCPUutilization:100%WorkerThread:Total:18Running:9Idle:4MaxLimit:32767MinLimit:20:055>!runawayUserModeTimeThreadTime41:7380days2:29:41.32840:c300days2:28:57.90635:17ec0days2:28:03.21837:5780days1:50:50.87536:15500days1:50:01.07834:e340days1:48:53.50033:3800days1:48:09.531执行时间长达2小时并发字典55OSThreadId:0x738(41)ChildSPIPCallSite000000f505e0e69000007ff873e69594System.Collections.Generic.Dictionary`2[[System.__Canon,mscorlib],[System.__Canon,mscorlib]].FindEntry(System.__Canon)000000f505e0e70000007ff873e40ae4System.Collections.Generic.Dictionary`2[[System.__Canon,mscorlib],[System.__Canon,mscorlib]].TryGetValue(System.__Canon,System.__CanonByRef)000000f505e0e74000007ff818c92704Kingdee.BOS.Web.DynamicForm.DynamicWebFormState.GetControlState(System.String)OSThreadId:0x17ec(35)ChildSPIPCallSite000000f50004dc5000007ff873e66469System.Collections.Generic.Dictionary`2[[System.__Canon,mscorlib],[System.__Canon,mscorlib]].Insert(System.__Canon,System.__Canon,Boolean)000000f50004dcf000007ff818c926d7Kingdee.BOS.Web.DynamicForm.DynamicWebFormState.GetControlState(System.String)堆栈信息56并发字典读/写都有锁代码570:120>!clrstackOSThreadId:0x2284(120)ChildSPIPCallSite000000ba201be26800007ff91770079a[GCFrame:000000ba201be268]000000ba201be33000007ff91770079a[GCFrame:000000ba201be330]000000ba201be38800007ff91770079a[HelperMethodFrame:000000ba201be388]System.Threading.Monitor.Enter(System.Object)0:124>!syncblkIndexSyncBlockMonitorHeldRecursionOwningThreadInfoSyncBlockOwner774000000bed165f3f811000000bee02896102284120000000bd418c48d8System.Object-----------------------------Total29261CCW16RCW5ComClassFactory0Free3090锁58使用某个对象时,需要了解内部实现机制锁的问题publicobjectGet(stringname){objectresult=null;this._lock.AcquireRead();try{result=base.BaseGet(name);}finally{this._lock.ReleaseRead();}returnresult;}publicvoidSet(stringname,objectvalue){this._lock.AcquireWrite();try{base.BaseSet(name,value);}finally{this._lock.ReleaseWrite();}}59一般存在两个问题同一个对象,如果同时有对象进行读写操作,如果不加锁定,将可能访问到不完整的对象从而导致问题对象并不需要锁定,但却进行了锁定,导致并发能力下降需要注意是否需要锁明确需要锁定的对象,并且避免锁定this减少不必要的锁定注意静态变量的使用注意缓存对象的使用,特别是对象中又包含对象的情况代码中不能出现System.Console.Write…的方法并发访问600:054>!threadpoolCPUutilization:100%WorkerThread:Total:15Running:6Idle:4MaxLimit:32767MinLimit:2Linq查询61OSThreadId:0x109c(38)ChildSPIPCallSite0000002d92c2cac000007ff85bed403eKingdee.BOS.Business.PlugIn.InfoComponent.ConsoleMyTabWorkPlugIn+c__DisplayClass2e.b__25(Kingdee.BOS.Orm.DataEntity.DynamicObject)0000002d92c2caf000007ff8af3fc874System.Linq.Enumerable+WhereArrayIterator`1[[System.__Canon,mscorlib]].MoveNext()0000002d92c2cb3000007ff8af3fa4e7System.Linq.Buffer`1[[System.__Canon,mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1)0000002d92c2cbc000007ff8af3fe808System.Linq.OrderedEnumerable`1+d__1[[System.__Canon,mscorlib]].MoveNext()0000002d92c2cc1000007ff8af3fa482System.Linq.Buffer`1[[System.__Canon,mscorlib]]..ctor(System.Collections.Generic.IEnumerable`1)0000002d92c2cca000007ff8af4001b8System.Linq.Enumerable.ToArray[[System.__Canon,mscorlib]](System.Collections.Generic.IEnumerable`1)0000002d92c2cd1000007ff85bd429b2Kingdee.BOS.Business.PlugIn.InfoComponent.ConsoleMyTabWorkPlugIn.IsMyInstChanged(Kingdee.BOS.Orm.DataEntity.DynamicObject[])堆栈620:038>!mdt0000002c9a93a3700000002c9a93a370(System.Linq.Enumerable+WhereArrayIterator`1[[Kingdee.BOS.Orm.DataEntity.DynamicObject,Kingdee.BOS.DataEntity]])threadId:0x33(System.Int32)state:0x1(System.Int32)current:0000002b89232b58(Kingdee.BOS.Orm.DataEntity.DynamicObject)source:0000002d75decca0(Kingdee.BOS.Orm.DataEntity.DynamicObject[],Elements:45490)predicate:0000002c9a93a330(System.Func`2[[Kingdee.BOS.Orm.DataEntity.DynamicObject,Kingdee.BOS.DataEntity],[System.Boolean,mscorlib]])index:0x93f9(System.Int32)0:038>!objsize0000002c9a93a370sizeof(0000002c9a93a370)=24452688(0x1751e50)bytes(System.Linq.Enumerable+WhereArrayIterator`1[[Kingdee.BOS.Orm.DataEntity.DynamicObject,Kingdee.BOS.DataEntity]])对象63代码64静态/共用字典对象65OSThreadId:0x2588(47)000000220258AE980000001faa5cf8b8Kingdee.BOS.App.Core.BusinessFlow.ReserveLogic.ReserveLinkConvertPoxyOSThreadId:0x2588(49)0000002201689C6800000020b055aef8Kingdee.BOS.App.Core.BusinessFlow.ReserveLogic.ReserveLinkReleasePoxy0:049>!do0000001eaa9f3628Name:System.Collections.Generic.Dictionary`2[[System.String,mscorlib],[Kingdee.BOS.Core.Metadata.Expression.FuncDefine.FunctionManage,Kingdee.BOS.Core]]MethodTable:00007ff9bbcdbbd0EEClass:00007ffa153daf60Size:80(0x50)bytesFile:C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dllFields:MTFieldOffsetTypeVTAttrValueName00007ffa15a1922040018588System.Int32[]0instance00000020aa025670buckets00007ffa1650d088400185910...non,mscorlib]][]0instance00000020aa025698entries00007ffa15a19288400185a38System.Int321instance1count不同的对象共享静态对象,访问对象记录为空对象66代码670:125>!threadpoolCPUutilization:100%WorkerThread:Total:95Running:95Idle:0MaxLimit:32767MinLimit:4126个线程在执行***.K3.SCM.WMS.BusinessPlugIn.PickRequest.OutStock+c__DisplayClass0_1.b__0()序列化68000000aa1915e63000007ff89397f29dNewtonsoft.Json.Linq.JToken.FromObjectInternal(System.Object,Newtonsoft.Json.JsonSerializer)000000aa1915e6a000007ff89397f11fNewtonsoft.Json.Linq.JObject.FromObject(System.Object,Newtonsoft.Json.JsonSerializer)000000aa1915e70000007ff89397f0e2Newtonsoft.Json.Linq.JObject.FromObject(System.Object)000000aa1915e75000007ff89397ef7c***.K3.SCM.WMS.BusinessPlugIn.PickRequest.OutStock+c__DisplayClass0_1.b__0()--对象大小12MB0:110>!objsize000000a8e311d028sizeof(000000a8e311d028)=12365232(0xbcadb0)bytes(BIP.K3.SCM.WMS.BusinessPlugIn.PickRequest.OutStock+<>c__DisplayClass0_1)69publicIOperationResultGenerateOutStockBill(DynamicObject[]bills,Contextctx){IOperationResultoperationResult=newOperationResult();List<string>list=newList<string>();for(inti=0;i<bills.Length;i++){DynamicObjectdynamicObject=bills[i];using(KDTransactionScopekDTransactionScope=newKDTransactionScope(TransactionScopeOption.Required))//这个事务应该放在for循环外面{stringtype=Convert.ToString(dynamicObject.get_Item("FBusinessType"));stringsrcBillNo=Convert.ToString(dynamicObject.get_Item("FHeadSrcBillNo"));stringbillNo=Convert.ToString(dynamicObject.get_Item("billno"));IOperationResultr=newOperationResult();....//json对象序列化导致了高CPU的开销srcBillNo,JObject.FromObject(r).ToString()//另外这里用代理的目的是?Actionarg_38E_1=delegate{MyLogger.Save(ctx,DateTime.Now,type,billNo,"","",srcBillNo,JObject.FromObject(r).ToString(),"");};代码70通过先序列化再反序列化的方式来生产一个新的对象序列化的成本相对较低反序列化的成本非常高,特别是复杂对象如果数据并不存在修改的可能,那么就不将对象进行深度克隆是否可以用浅拷贝慎用CreateCopyformatter.Serialize(stmSeriBuff,obj);stmSeriBuff.Position=0;ret=formatter.Deserialize(stmSeriBuff);stmSeriBuff.Close();stmSeriBuff.Dispose();formatter=null;71表达式定义的脚本如下用in子句替代or的实现方式Python脚本引起CPU100%问题FMaterialID_FMaterialGroup_FNumber=='0507'and(FDepartmentId_FNumber=='WSJY012'orFDepartmentId_FNumber=='WSJY012.01'orFDepartmentId_FNumber=='WSJY012.02'orFDepartmentId_FNumber=='WSJY001'orFDepartmentId_FNumber=='WSJY002'orFDepartmentId_FNumber=='WSJY003'orFDepartmentId_FNumber=='WSJY003.01'orFDepartmentId_FNumber=='WSJY003.02'orFDepartmentId_FNumber=='WSJY003.03'orFDepartmentId_FNumber=='WSJY003.04'orFDepartmentId_FNumber=='WSJY003.05'orFDepartmentId_FNumber=='WSJY004'orFDepartmentId_FNumber=='WSJY004.01'orFDepartmentId_FNumber=='WSJY004.02'orFDepartmentId_FNumber=='WSJY004.04'orFDepartmentId_FNumber=='WSJY004.03'orFDepartmentId_FNumber=='WSJY007'orFDepartmentId_FNumber=='WSJY007.01'orFDepartmentId_FNumber=='WSJY007.02'orFDepartmentId_FNumber=='WSJY007.03'orFDepartmentId_FNumber=='WSJY007.04'orFDepartmentId_FNumber=='WSJY008'orFDepartmentId_FNumber=='WSJY008.01'orFDepartmentId_FNumber=='WSJY005'orFDepartmentId_FNumber=='WSJY005.01'orFDepartmentId_FNumber=='WSJY006'orFDepartmentId_FNumber=='WSJY006.01'orFDepartmentId_FNumber=='WSJY009'orFDepartmentId_FNumber=='WSJY009.01'orFDepartmentId_FNumber=='WSJY009.02'orFDepartmentId_FNumber=='WSJY009.03'orFDepartmentId_FNumber=='WSJY010'or'WSJY014'inFDepartmentId_FNumberor'WSJY011'inFDepartmentId_FNumberor'WSJY013'inFDepartmentId_FNumberor'WSJY015'inFDepartmentId_FNumber)72因素对象很大导致循环次数高主动使用锁,但控制策略上考虑不够完善非线程安全的静态变量在多线程下使用递归调用小结73表现某几个CPU的内核时间非常高,高峰时100%,功能响应时间整体下降明显,特别是多次网络交互的功能,如批量选择基础资料回填,性能下降可能超过10倍或者更多。ping服务器地址,发现网络延迟非常高防火墙引发的高CPU内核时间74•设置w3wp.exe的CPU相关性,取消对应的CPU,发现内核时间依然很高,说明导致内核时间高非代码引发的•优化网控相关设置后,依然高•禁用防火墙“网络和主机漏洞缓解”后,问题得到解决防火墙引发的高CPU内核时间75结论:URL变化引发防火墙行为的变化防火墙引发的高CPU内核时间76小结CPU使用率是否100%线程运行时间长时间运行的线程查看堆栈信息重复方法调用锁其他线程有类似的堆栈查看对象对象大小是否静态对象是否并发字段查看代码检查代码,确认原因CPU内核时间某些CPU内核时间100%?检查防火墙的设置77避免深度循环静态对象访问注意锁的控制并发字典读写都是上锁的大对象避免用linq进行查询序列化/反序列化复杂对象的成本非常高是否需要锁操作Python表达式避免or太多条件还有多线程……小结78cputest.exex示例CPU使用率持续高位79第四章高内存80互动高内存有哪些表现?81数据库内存不足内存泄漏操作数据范围过大目录82一个误区SQLServer内存持续保持高位,内存不够用了,影响性能实际SQLServer充分使用设置的最大内存,来保证性能最大化数据库内存不足83SELECTDATEADD(ss,(-1*((cpu_ticks/CONVERT(float,(cpu_ticks/ms_ticks)))-[timestamp])/1000),GETDATE())ASEventTime,CONVERT(xml,record)ASrecordFROMsys.dm_os_ring_buffersCROSSJOINsys.dm_os_sys_infoWHEREring_buffer_type='RING_BUFFER_RESOURCE_MONITOR'查询内存不足语句84将物理内存设置为最小值128MBSQL查询可能出现下面错误通过SSMS查看属性出现错误查询内存不足记录示例Msg8645,Level17,State1,Line103等待资源池'internal'(1)中的内存资源来执行该查询时发生超时。请重新运行该查询。85RESOURCE_MEMPHYSICAL_LOW说明物理内存少IndicatorsSystem=0非系统级问题,如非0表示系统级问题IndicatorsProcess=2说明低物理内存。1:高物理内存2:低物理内存4:低虚拟内存示例86netstartmssqlserver/f/msqlcmd-A修改最大内存大小NetstopmssqlserverNetstartmssqlserver内存设置太小引起SQLServer无法启动怎么解决87默认2TB不合理专用机器,设置最大物理内存-2GB数据库设置88事件句柄Dynamic关键字数据库连接内存泄漏89!eeheap–gc!dumpheap–min85000–stat!objsize!gcroot!clrstack!do!mdt!dso!mdsoWindbg命令90有+必须有-Element.KeyChanged+=newEventHandler<KeyChangedArgs>(Element_KeyChanged);element.KeyChanged-=newEventHandler<KeyChangedArgs>(Element_KeyChanged);越来越少使用,这种情况发生的概率越来越低绑定事件91语法dynamico=System.Activator.CreateInstance(t);解决不使用dynamic关键字或者调整为objecto=System.Activator.CreateInstance(t);频繁的反射调用也存在类似问题Dynamic导致的内存泄露92大量RuntimeBinder对象Kingdee.BOS.Context多代码需要设置view=null反射调用镜像文件特征00007fffdc06d4b8278731422452836496Microsoft.CSharp.RuntimeBinder.Semantics.Scope00007fffdc06d080278733212452852248Microsoft.CSharp.RuntimeBinder.Semantics.LocalVariableSymbol00007fffdc06d160278731422675821632Microsoft.CSharp.RuntimeBinder.Semantics.AggregateDeclaration--客户环境00007fff84124b1812202861502112Kingdee.BOS.Context---正常其他客户00007ffb8486f1e8418200640Kingdee.BOS.Contextvarview=(IDynamicFormViewService)Activator.CreateInstance(type)93表现连接池用完提示连接已关闭Datareader一定要用using实现了Idispose的类型,需要用using非托管代码,一定要用using数据库连接使用using94引入引出打印/打印预览成本计算MRP计算BOM展开自动补号服务连续/合并套打物料分配巡检计划大内存操作95一次读取太多数据到应用服务器--SQL语句无过滤条件返回369W行数据SELECT[kd_t_Cust_Entry100066].[FEntryID],[kd_t_Cust_Entry100066].[FID]FROM[kd_t_Cust_Entry100066]INNERJOIN[T_SAL_OUTSTOCK]ON[kd_t_Cust_Entry100066].[FID]=[T_SAL_OUTSTOCK].[FID]0:062>!gcroot000000a507566908Thread211c:000000a50d9ec5f000007fff19eb03e8Kingdee.BOS.Collections.Generic.ForWriteList`1[[System.__Canon,mscorlib]].AddRange(System.Collections.IEnumerable)rdi:->000000a368416cc0Kingdee.BOS.Collections.Generic.ForWriteList`1[[System.Object,mscorlib]]->000000a507566908System.Object[]AddressMTSize(2.5GB)000000a50756690800007fff15bcba3083886402,546,258,800从数据库读取369w行数据转换为对象字典耗费了2.5GB左右的空间,引起内存突增96引出Kingdee.BOS.Business.Bill.Operation.ExportData.GetExportData()一次引出59W数据97根源数据量太大,内存资源不足建议对象需要及时释放避免一次性读取所有数据如果客户组织很多,增加多台计算服务器进行月末业务的处理万一有全表的引出,错开业务高峰共有并且不变的资源考虑使用缓存尽量采用标准的语法,减少linq,匿名委托等使用非托管代码一定要使用using数据库连接需要使用using小结98memory.exe示例内存溢出连接泄漏99第五章系统崩溃100互动所有客户端突然闪退如何捕获?101将下面的内容保存.reg注册表的文件,导入到注册表DumpFolder:文件生成的位置(d:\dumps),文件夹必须存在,可以修改DumpCount:最多生成文件个数前提条件:WindowsErrorReporting服务必须启动自动抓取dumpWindowsRegistryEditorVersion5.00[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\WindowsErrorReporting\LocalDumps\w3wp.exe]"DumpFolder"=hex(2):64,00,3a,00,5c,00,64,00,75,00,6d,00,70,00,73,00,00,00"DumpCount"=dword:00000002"DumpType"=dword:00000002[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\AeDebug]"Debugger"=-[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]"DbgManagedDebugger"=-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WindowsNT\CurrentVersion\AeDebug]"Debugger"=-[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]"DbgManagedDebugger"=-102!pe!dumpheap–typeException!analyze–v!do!clrstackWindbg命令103System.StackOverflowExceptionSystem.AccessViolationException目录104递归System.StackOverflowException105字段相互引用导致的循环触发System.StackOverflowException106单据字段服务规则引发的死循环System.StackOverflowException107值更新事件导致堆栈溢出System.StackOverflowException108表达式中or条件过多,python无法解析System.StackOverflowException109内存镜像中范围下面的地址堆栈信息访问了非托管代码System.AccessViolationException/k3cloud/Kingdee.K3.FIN.ER.Mobile.Business.PlugIn.MobileReimbV3.MobileReimbService.GetGlobalERConfig.kdmaUnsafeIISMethods.MgdGetCurrentNotificationInfo(nativeRequestContext,outnum,outisPostNotification,outnum2);110ODP.NET非托管代码(C++实现,Oracle已经不再更新)部署多台应用服务器,减少全员闪退System.AccessViolationException111定义服务规则时需要注意字段间是否可能会相互触发嵌套代码需要有明确退出条件避免值更新事件嵌套定义表达式控制数量非托管代码不受.NET运行时控制,另外也是不安全的,所以需要做好充分的测试验证小结112第六章阻塞/死锁113很多人经常搞混有联系,但不一样死锁实际可以看作阻塞的一种特殊情况互动114锁阻塞死锁目录115锁定是MicrosoftSQLServer数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制锁现有授予模式请求模式ISSUIXSIXX意向共享(IS)是是是是是否共享(S)是是是否否否更新(U)是是否否否否意向排他(IX)是否否是否否意向排他共享(SIX)是否否否否否排他(X)否否否否否否116资源说明RID用于锁定堆中的单个行的行标识符。KEY索引中用于保护可序列化事务中的键范围的行锁。PAGE数据库中的8KB页,例如数据页或索引页。EXTENT一组连续的8页,例如数据页或索引页。HoBT堆或B树。用于保护没有聚集索引的表中的B树(索引)或堆数据页的锁。TABLE包括所有数据和索引的整个表。FILE数据库文件。APPLICATION应用程序专用的资源。METADATA元数据锁。ALLOCATION_UNIT分配单元。DATABASE整个数据库。锁资源117阻塞1181:会话54被58阻塞2:会话58在执行修改f1字段的全表操作3:会话54在执行修改f2字段的全表操作4:修改的表对应的数据库为tempdb5:锁的类型为RID(行锁),等待的资源描述为5:40:0,相关的对象为20896702282518364166:请求的锁是U(更新锁)7:操作等待了超过了300秒抓取阻塞SQL语句119阻塞示例120阻塞抓取方式—扩展事件121阻塞抓取方式—扩展事件122阻塞抓取方式—扩展事件123阻塞抓取方式—sqlprofiler124阻塞抓取方式—sqlprofiler125保证表存在有效的索引事务不能过长执行事务的过程中,不要与前端进行交互保证表的碎片和统计信息是最优的如何避免126获取到阻塞信息如下:等待会话执行UPDATE语句阻塞会话执行SELECT语句被误解的一种阻塞—读为何阻塞更新?新建会话(90)执行的SQL,按1,2,3的方式逐条执行,不提交事务新建会话(128)执行的SQL,按1,2的方式逐条执行127系统将自动杀掉成本低的会话特别的类型:并行计划引起的死锁(https://vip.kingdee.com/article/103496512717689856)死锁128死锁展示图形文字XML死锁信息129死锁示例130实时抓取dbcctraceon(1204,1222,3605,-1)/Sp_readerrorlogSQLServerprofiler错误和警告事件锁事件下的死锁图形DMV获取(SQLServer启动后失效)抓取死锁的方法SELECTXEvent.query('(event/data/value/deadlock)[1]')ASDeadlockGraphFROM(SELECTXEvent.query('.')ASXEventFROM(SELECTCAST(target_dataASXML)ASTargetDataFROMsys.dm_xe_session_targetsstJOINsys.dm_xe_sessionssONs.address=st.event_session_addressWHEREs.name='system_health'ANDst.target_name='ring_buffer')ASDataCROSSAPPLYTargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]')ASXEventData(XEvent))ASsrc;13112041321222133SQLServerprofiler134SQLServerprofiler135扩展事件系统自动生成xel文件(可以查看历史数据)抓取死锁的方法136除了阻塞注意事项外访问表的顺序要一致字段不要包括在多个索引中如何避免137短暂的阻塞是正常的长时间的阻塞是有害的SQL语句语句简单好于复杂事务越短越好表需要建立有效的索引表的碎片和统计信息需要保证最优执行SQL过程中避免与前端进行交互设置适当的超时时间,避免长时间阻塞小结138第七章低效SQL139低效SQL的特点碰到这种情况,会怎么做?看执行计划么?互动140影响查询计划的因素索引统计信息数据量关联表的数量解决方式减少编译时间降低SQL语句的复杂程度利用参数化执行SQL,减少重新编译成本降低IO读取数量增加有效索引临时表排序…影响SQL执行效率的因素141SQL语句解读索引统计信息执行计划常见的一些问题目录142FROMCorpDB.dbo.OrderHeaderohINNERJOINCorpDB.dbo.OrderDetailodINNERJOINCorpDB.dbo.CustomercustONoh.OrderId=od.OrderIdONoh.CustomerId=cust.CustomerIDWHEREcust.State='NE'GROUPBYod.ProductIdHAVINGSUM(od.Quantity)>=20SELECTod.ProductId,SUM(od.Quantity)-20ExcessOrdersORDERBYod.ProductIdTOP5;SQL语句解读—我们的视角143SQL语句解读—SQLServer视角144SQL语句解读—解析树145•逻辑运算符内部实现•开始为逻辑运算符,包含逻辑和物理运算符•0到无限个输入,1个输出•SQLServer将在优化的各个阶段输出解析树•特殊跟踪标志将触发输出•使用用于初始化Memo结构SQL语句解读—解析树MorelikeaWHEREclauseMorelikeaSELECT...

1、当您付费下载文档后,您只拥有了使用权限,并不意味着购买了版权,文档只能用于自身使用,不得用于其他商业用途(如 [转卖]进行直接盈利或[编辑后售卖]进行间接盈利)。
2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。
3、如文档内容存在违规,或者侵犯商业秘密、侵犯著作权等,请点击“违规举报”。

碎片内容

金蝶云星空 金蝶云·星空性能分析和优化.pdf

确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息
QQ群
  • 答案:my7c点击这里加入QQ群
支持邮箱
微信
  • 微信