ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

用友U8越用越慢?数据库与SQL Server配置优化实战指南

用友U8越用越慢?数据库与SQL Server配置优化实战指南 1. 用友U8越用越慢问题出在哪用友U8跑得慢到底是服务器不行还是设置不对这个问题我在客户现场遇到过太多次了。一个做了七八年的U8账套数据量没到天塌下来的程度但客户端点个保存要转圈十几秒月末结账跑批跑半个多小时财务那边已经炸锅了。换服务器吧预算又没批下来不换吧天天被催。实际上大部分U8性能问题根本轮不到换硬件。真正的问题往往藏在SQL Server配置、数据库索引、应用服务器参数、甚至一台工作站的客户端环境里。你只是没用对方法把这些点找出来。这篇东西不打算讲那种“建议升级服务器配置”的废话而是把我这几年在U8性能优化上真正动手做过、验证过有效的方案整理出来从服务器硬件、操作系统、数据库参数、U8应用层配置到常见故障排查一条一条说清楚。如果你正在管一套U8系统不管你是企业IT、财务信息化负责人还是刚接手U8的运维新人这篇内容都适合你。不需要你有多深的数据库底子按着步骤来至少能把那些“看起来只能换服务器”的问题压下去一截。1.1 性能问题通常不是“一处”造成的先说一个容易踩的坑很多人一上来就调某个参数比如把SQL Server最大内存调大或者把U8缓存调高结果过了几天又卡了。原因是U8的性能链路特别长一台客户端发起的操作要经过网络、应用服务器、数据库服务、存储系统最后还要把数据传回来任何一个环节堵住你看到的都是同一个现象——慢。我习惯把U8性能问题分成四层来看客户端层浏览器缓存、U8客户端组件、杀毒软件实时扫描、网络链路延迟应用服务层U8应用服务器配置、缓存目录、并发会话数、中间层组件状态数据库层SQL Server内存、并行度、索引碎片、统计信息、日志文件、临时库存储层磁盘类型、阵列卡读写策略、磁盘剩余空间、备份任务对I/O的抢占。这四层里数据库层和存储层是最常见的性能瓶颈来源约占七八成。你说服务器“配置够高”却依然慢多半是数据库或存储配置没有跟上硬件的水平。1.2 性能优化前要先建一个“体检基线”优化最忌讳的是没有数据支撑就开始动手。你连当前系统的正常基线都不知道改完参数到底有没有效果全靠“感觉快了”这种方案我从来不认。我建议在动手前先用一天到两天收集一套基准数据包括服务器CPU平均使用率、峰值使用率内存可用量、SQL Server占用内存量磁盘队列长度、读/写延迟数据库文件大小、日志文件大小、数据库碎片率几个典型业务操作的耗时比如开一张销售订单、保存一张采购入库单、跑一次月末结转。这些数据后面每一轮优化做完都要重新采集一遍用来对比效果。优化不是玄学是要能拿数据说话的。有了基线你才知道问题到底是CPU不够、内存不足、还是索引烂到没法看。我见过一台服务器CPU常年5%但业务还是卡最后发现是数据库索引碎片率超过70%跟硬件一点关系都没有。2. 服务器硬件层面的优化2.1 CPU与内存先压榨再换机硬件能不动就不动但你必须搞清楚当前硬件到底卡在哪。U8是典型的OLTP系统特点是大量短小频繁的增删改查操作对单核主频和内存容量都很敏感。很多老服务器用的是至强E5系列核心数不少但单核主频只有2.0GHz甚至更低这种CPU跑U8的并发并发低峰期还行一旦月末所有人同时做单据CPU会直接飙升到90%以上。优化思路有两个方向一是确认服务器电源计划有没有被设成“节能”或“平衡”很多服务器在BIOS和Windows里都没有开启高性能模式CPU一直锁在最低频率性能直接腰斩。这个不花一分钱但经常被忽略。二是SQL Server默认会吃掉所有可用内存导致操作系统和U8应用服务没内存可用频繁换页。这时候内存再大也没有用。后面我会专门讲SQL Server内存上限怎么设置。2.2 磁盘I/OSSD带来的体感提升最直接如果你只能做一项硬件改造我强烈建议先把数据库所在的磁盘换成SSD效果立竿见影。机械硬盘的随机读写延迟一般在10毫秒左右SSD的随机读写延迟不到0.1毫秒相差两个数量级。U8的数据库文件、日志文件、TempDB全部都要放在SSD上。尤其是TempDB它承担着排序、临时表、行版本控制等操作如果TempDB在机械盘上月末跑批就是一场灾难。如果服务器没法换SSD还有一个折中方案把TempDB和日志文件挪到另一块物理盘上和数据库数据文件分开减少磁头寻道竞争。就算都是机械盘分离I/O也比放在一块盘上强很多。另外检查一下磁盘阵列的读策略有的RAID卡默认开启读缓存有的没开开启后对读多写少的U8场景有明显帮助。2.3 网络与虚拟化环境的“隐形损耗”服务器本身没问题但依然慢的时候要检查网络和虚拟化环境。很多U8客户端离服务器跨了三层交换机中间还有防火墙做规则过滤一次单据保存要来回传输几十个小包网络延迟哪怕只多10毫秒体感就会很难受。我自己处理过一个案例客户端的Ping服务器延迟只有1毫秒但U8操作非常卡最后发现是防火墙对U8端口做了深度包检测数据包被拆开重组直接把性能拖垮了。后来在防火墙上把U8应用服务器和SQL Server之间的端口加入白名单关闭深度检测问题就消失了。虚拟化环境下还要注意CPU预留和内存预留。VMware虚拟机上跑U8如果宿主机CPU超分比过高子机之间互相抢资源U8的并发响应就会很不稳定。建议给U8数据库虚拟机设置CPU预留至少保证有多少物理核就预留多少份内存也尽量做预留别让SQL Server的内存被其他虚拟机回收。3. 操作系统与数据库配置优化3.1 Windows Server和SQL Server版本选型这里说的选型不是让你现在去换系统而是让你确认当前环境是不是“适合跑U8的组合”。Windows Server 2008 R2搭配SQL Server 2008 R2是老用户最常见的配置但这套组合在微软主流支持结束后很多驱动和补丁都不再更新SSD的NVMe驱动可能会找不到、磁盘性能发挥不出来。如果条件允许建议在虚拟化平台上新开一台Windows Server 2016/2019/2022虚拟机安装SQL Server 2016/2019再把U8账套做备份恢复过去。U8版本如果较老要先确认官方支持的操作系统和数据库版本。用友U8 V13.0之后的版本对SQL Server 2016以上的支持都比较完整。跨版本升级数据库之前一定要先在测试环境模拟一次避免系统表兼容性问题。3.2 电源计划、虚拟内存与杀毒软件排除目录登录Windows Server打开“控制面板-电源选项”把电源计划改成“高性能”。这一步在物理机和虚拟机上同样重要。虚拟机上如果宿主机做了CPU节能策略子机内部再不改电源计划性能损耗更明显。虚拟内存方面系统盘和数据库盘都“系统管理的大小”就好不建议关闭页面文件。SQL Server虽然主要使用内存但遇到内存压力时仍需要页面文件兜底。至少保证物理内存的1.5倍页面文件可用。杀毒软件是另一个容易被忽视的隐形杀手。很多企业服务器装了360、火绒、McAfee之类的杀毒软件实时防护默认扫描所有磁盘读写。U8的数据文件、日志文件、临时目录每秒都有大量I/O如果杀毒软件逐文件扫描磁盘性能会大幅下降。至少要把以下路径加入杀毒软件排除列表U8安装目录默认通常是C:\U8SOFTU8缓存目录一般在安装目录下的Cache、Temp目录SQL Server数据文件目录如D:\MSSQL\DATASQL Server备份目录。3.3 SQL Server内存上限与最大并行度这是整个优化里最关键的两个参数。先说内存。SQL Server只要不限制最大内存就会把主机上几乎所有空闲内存都吃掉导致操作系统和U8应用服务无内存可用Windows不停把内存内容写入页面文件。正常的做法是给SQL Server设置一个最大内存上限。通用经验公式如果服务器内存为64GB操作系统预留4GBU8应用服务和中间件预留4GBSQL Server最大内存设置为48-52GB剩下留给文件缓存自动管理。如果是专用数据库服务器就按总内存的80%左右给SQL Server。设置方法是在SQL Server Management Studio里右键服务器属性内存页修改“最大服务器内存MB”。然后是最大并行度MAXDOP。很多U8数据库服务器保持默认0也就是允许SQL Server使用全部CPU核做并行查询。听起来是好事但在U8这种短事务为主的环境里并行查询反而会造成CPU上下文切换过高个别查询还会被并行操作“锁死”。对于8核以下的服务器我建议把最大并行度设置为2或416核以上设置为4到8同时把“并行查询阈值”Cost Threshold for Parallelism从默认5调到50避免那些小查询也走并行计划。用T-SQL设置更直接EXEC sp_configure max degree of parallelism, 4; EXEC sp_configure cost threshold for parallelism, 50; RECONFIGURE WITH OVERRIDE;3.4 自动增长、自动收缩与自动统计信息数据库文件自动增长和自动收缩这两个设置直接影响日常操作稳定性。很多人没动过默认配置数据文件一次增长只有几MBU8在月末跑批时数据量突然暴涨数据库要反复等待文件扩容整个系统就卡住了。建议把数据文件和日志文件的初始大小设置为当前文件大小的1.5倍自动增长按固定MB增长不要用百分比。日志文件增长步长设置为512MB或1GB。例如当前数据文件20GB就设初始大小30GB自动增长增长量512MB。这一步需要提前做好磁盘空间规划。自动收缩则要关闭。数据库文件频繁收缩会导致索引碎片急剧增加下次查询又要重新整理数据页性能越来越差。U8日常维护不需要自动收缩如果实在要收缩放在业务低峰期手动执行一次即可。统计信息对查询计划影响非常大。SQL Server默认自动更新统计信息但触发条件往往滞后对于U8这种数据变化频繁的系统建议在每天低峰期手动更新一次关键表的统计信息。后面会给出具体脚本。4. 用友U8应用层参数调整4.1 U8应用服务器与数据库服务器分离很多小企业把U8应用服务和SQL Server装在同一台服务器上预算省了一点但一到业务高峰期CPU和内存被两边抢来抢去做什么都慢。条件允许的话强烈建议把U8应用服务器和数据库服务器拆到两台机器上。分离之后数据库服务器专心做数据读写应用服务器处理客户端接入、中间层调用和报表计算两台机器的负载都下来了。而且你还能针对每一层做独立优化比如数据库服务器锁内存、应用服务器调缓存互不影响。如果你的服务器实在不够拆至少在应用层面避免在同一台机器上安装其他重型软件比如邮件服务器、文件服务器、ERP系统的报表服务这些都会和U8抢资源。4.2 缓存目录与临时文件清理U8在使用过程中会在服务器和客户端生成大量缓存文件这些文件积攒到一定量级后可能出现登录慢、单据打开慢、甚至界面卡死的问题。我遇到过U8客户端缓存目录里有几万个临时文件清理之后打开单据的速度立刻恢复正常。服务器端需要重点关注这几个位置U8安装目录下的C:\U8SOFT\CacheU8的日志目录通常在C:\U8SOFT\LogsWindows临时目录C:\Windows\TempSQL Server的备份目录确认是否有大量过期备份未清理。客户端缓存目录一般在C:\Users\用户名\AppData\Local\UFSoft里面可能有多套账套的缓存子目录。建议在客户端比较少的情况下手动删除然后重新登录U8。但不建议直接删除整个目录最好先备份保留确认正常后再清理。4.3 客户端连接配置和常见反例客户端连U8慢除了网络问题还有一个常见原因是客户端机器上安装了多个版本的U8或者曾经装过旧版本又没卸载干净导致组件注册混乱。这时U8检测环境会反复报错浪费大量时间。规范的做法是客户端统一使用与服务器一致的U8版本安装时以管理员身份运行安装完成后先重启再登录。如果出现“登录时读取数据源失败”或者很慢检查C:\Windows\System32\drivers\etc\hosts文件确保服务器IP和计算机名解析正常不要配置成解析到外网地址。还有一个小细节U8客户端默认使用TCP连接数据库服务器如果服务器名是计算机名而客户端无法解析会在等待DNS超时后才自动回退到IP连接。这时候把服务器IP直接写到客户端hosts文件里就会快很多。5. 数据库与账套数据专项优化5.1 索引碎片整理优化效果最明显的一步我每次去客户现场做U8优化第一个必查的就是索引碎片。索引碎片率一高SQL Server查询时要把大量数据页读取出来还要做多次随机I/O性能直接崩掉。怎么查碎片可以用这条SQLSELECT OBJECT_NAME(ips.object_id) AS TableName, i.name AS IndexName, ips.avg_fragmentation_in_percent, ips.page_count FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, LIMITED) ips JOIN sys.indexes i ON ips.object_id i.object_id AND ips.index_id i.index_id WHERE ips.avg_fragmentation_in_percent 30 ORDER BY ips.avg_fragmentation_in_percent DESC;执行之后你会看到哪些索引碎片超过30%。对碎片率在30%到50%之间的索引建议做重组ALTER INDEX REORGANIZE对超过50%的索引做重建ALTER INDEX REBUILD。U8数据库中单据主表和子表的数据量非常大像RdRecord收发记录主表、RdRecords收发记录子表、SO_SOMain销售订单主表、SO_SODetails销售订单子表这些表的索引碎片经常超过60%。重建索引的通用语句ALTER INDEX ALL ON RdRecord REBUILD WITH (ONLINE ON, SORT_IN_TEMPDB ON);注意ONLINE重建需要SQL Server企业版如果你用的是SQL Server标准版只能离线重建这时候务必选择业务低峰期执行。重建过程中会锁表业务外面看起来就是“卡死”。整理碎片不是一次性的任务我建议每个月低峰期跑一次碎片检查碎片率高的索引重建一遍。这是性价比极高的一项维护。5.2 缺失索引与无用索引排查碎片之外缺失索引是另一个隐藏炸弹。SQL Server运行时会记录哪些查询因为缺少索引而发生了大量逻辑读并生成缺失索引建议。用这条SQL可以查SELECT migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks migs.user_scans) AS improvement_measure, mid.statement AS TableName, mid.equality_columns, mid.inequality_columns, mid.included_columns FROM sys.dm_db_missing_index_group_stats migs JOIN sys.dm_db_missing_index_groups mig ON migs.group_handle mig.index_group_handle JOIN sys.dm_db_missing_index_details mid ON mig.index_handle mid.index_handle ORDER BY improvement_measure DESC;从结果里挑improvement_measure靠前的几条在低峰期手动创建索引。但不要无脑把所有建议都加进去因为索引越多插入更新时的维护成本越高。一般只给U8的核心业务表添加缺失索引并且要控制单个表索引数量在5-8个以内。同时还要找“无用索引”也就是那些建了但几乎没被用过的索引。可以查SELECT OBJECT_NAME(s.object_id) AS TableName, i.name AS IndexName, s.user_seeks, s.user_scans, s.user_lookups, s.user_updates FROM sys.dm_db_index_usage_stats s JOIN sys.indexes i ON s.object_id i.object_id AND s.index_id i.index_id WHERE s.database_id DB_ID() AND s.user_seeks 0 AND s.user_scans 0 AND s.user_lookups 0 ORDER BY s.user_updates DESC;如果某张表的核心索引一次都没被查询用过而更新次数很高说明这个索引反而在拖累性能可以考虑删除。删除之前先备份创建脚本万一之后有业务用到还能恢复。5.3 统计信息更新与查询计划缓存统计信息是SQL Server生成执行计划的依据。如果统计信息过期SQL Server可能选错索引导致“明明有索引却不用”的怪现象。建议在每周维护窗口执行一次全库统计信息更新EXEC sp_MSforeachtable UPDATE STATISTICS ? WITH FULLSCAN;对于超大表几千万行FULLSCAN全表扫描会消耗较多时间可以改成抽样UPDATE STATISTICS RdRecord WITH SAMPLE 50 PERCENT;更新统计信息后执行计划会重新编译。但有时缓存里还有旧计划可以通过下面的命令清空当前数据库的执行计划缓存DBCC FREEPROCCACHE;这个操作不要在白天空闲时间做因为清空后所有查询都需要重新编译短时间CPU会升高。最好放在夜间维护窗口和索引重建一起跑。5.4 临时库和日志文件的合理设置SQL Server的TempDB是很多人容易忽略的性能点。U8在分组汇总、排序、报表计算时大量使用TempDB如果TempDB文件太小自动增长频繁或者只有一个数据文件并发写入会出现PAGELATCH等待数据库整体变慢。建议把TempDB设置为多个数据文件文件数量尽量和CPU核心数一致但通常不用超过8个每个文件大小设为一致避免SQL Server写文件时不均匀。例如8核服务器可以建8个数据文件每个初始大小2GB自动增长512MB。日志文件方面U8数据库如果设成了简单恢复模式日志文件一般不会无限增长。但很多企业为了做时间点恢复用了完整恢复模式却不做定期日志备份日志文件会越涨越大最后占满磁盘。日常维护中完整恢复模式下要定期做事务日志备份然后收缩日志文件。通用脚本BACKUP LOG [U8Data] TO DISK D:\Backup\U8Data_LogBackup.trn; DBCC SHRINKFILE (U8Data_log, 1024);日志文件初始大小尽量设置为一个合理较大会值例如4GB或8GB避免频繁自动增长。自动增长步长设为512MB以上增长方式用固定MB不要用百分比。5.5 数据量大的账套如何做归档如果你的U8账套已经用了五六年以上数据文件动辄几十GB这时候再怎么调索引和统计信息性能天花板已经很明显了。解决的根本思路是归档旧数据。U8本身提供了“业务数据清理”和“领导查询数据清理”等工具可以在系统管理里进行历史数据清理。但清理前必须确认业务流程已经完成比如旧年度的账已经结账、报表已经出具最好先把历史数据备份一份再清理。整理行业内的通用做法是保留年度账作为历史库在正式库只保留最近三个年度的业务数据。每年年初结账后把上年数据备份然后通过U8的“数据清理”功能清理旧年度业务单据。没有清理功能的模块也可以手动把历史年度数据导出备份到独立数据库再从生产库中删除。这一步做完数据库文件大小会明显下降索引重建、统计信息更新、备份恢复的速度都会快很多。很多客户在做完数据归档后前端单据操作的响应时间直接从几秒钟降到1秒以内。6. 常见问题与排查技巧实录6.1 安装时IE Web Control组件装不上怎么办这是个老问题U8安装时有个“IE Web Control”组件经常在Windows 7或Windows Server 2008 R2上安装失败。一开始我以为是安装包坏了后来发现多半是系统组件缺失或权限不够。排查步骤如下右键单击安装程序选择“以管理员身份运行”打开“控制面板-程序和功能-启用或关闭Windows功能”确认Internet Explorer 11或更高版本已启用如果系统里之前装过低版本U8先卸载干净尤其是杀毒软件建议临时退出手动注册相关DLL文件。在命令行窗口输入regsvr32 C:\Program Files (x86)\Common Files\Microsoft Shared\DAO\dao360.dll regsvr32 C:\Windows\System32\ieui.dll如果还不行直接到U8安装目录下的3rdPrograms\IEWebControl目录找到IEWebControl.msi右键安装。补充一点Windows 7上装IE Web Control失败还可能是IE的“增强安全配置”导致下载的ActiveX被拦截。可以先关闭IE ESC再安装装完再重新开启。6.2 成本模块ERP数据没跑通的原因分析成本ERP数据没有跑通是U8成本核算模块里非常常见的问题。表面现象是成本计算时报“没有数据”或“某成本对象材料费用为0”但实际原因五花八门。我建议按照这个顺序排查先查上游单据状态材料出库单、其他出库单、产成品入库单是否已经审核并记账。成本模块从存货核算模块取数只要一张单据没审核记账这一条数据链就是断的。再查成本核算方法U8支持品种法、分批法、分步法不同方法的取数逻辑差别很大。如果核算方法设置错了数据就算有也会跑到错误的地方。检查分配率设置公用材料分配率、人工费用分配率、制造费用分配率必须设置为“按产量”“按工时”或“按材料成本”等具体方式不能是空白。确认生产订单和成本对象是否匹配很多企业生产订单没有审核或者产品编码在成本BOM中不存在系统无法归集成本。查看成本计算日志U8成本计算会生成日志详细记录每一步取数来源和计算过程哪一步缺数据日志里基本都能看到。之前有个客户做了两个月成本数据都对不上我一查发现是因为材料出库单的仓库被设置成了“不参与成本核算”导致所有材料费用都没有取到。把这个仓库的核算属性改掉之后成本数据立刻跑通了。所以查数据没跑通别一门心思钻数据库先去看基础档案和业务规则设置。6.3 月末结账跑批慢的排查顺序U8月末结账跑批慢也是高频问题。跑批慢的本质是大量事务短时间内集中提交对数据库I/O、锁和TempDB形成并发压力。我建议按这个顺序排查第一步看TempDB是不是扛得住。如果TempDB只有一个文件而且还在机械盘上基本就是瓶颈。第二步查是否有长时间未提交的事务阻塞。用这条SQLSELECT session_id, blocked_by, wait_time, wait_type, last_wait_type FROM sys.dm_exec_requests WHERE blocking_session_id 0;如果跑批时间正好撞上有人在做报表查询后来者会一直等待跑批时间被无限拉长。第三步看索引碎片。月末跑批要更新大量库存台账和收发记录索引碎片高的时候更新一条记录要去读大量碎片页。第四步检查数据库自动增长是否频繁触发。日志文件增长一次几MB时跑批过程中的写操作会不断卡在文件增长等待上。从实战经验来看月末结账慢大多不是单一原因至少有两三个因素叠加。我习惯先做一次全库索引重建再调整日志增长再确认TempDB大小这串流程做完80%的跑批慢问题都能缓解。6.4 常用性能监控SQL脚本最后分享几个我现场常用的监控脚本建议保存下来遇到问题直接跑。查看当前阻塞和等待SELECT session_id, blocking_session_id, wait_type, wait_time, cpu_time, logical_reads FROM sys.dm_exec_requests WHERE blocking_session_id 0 OR wait_type NOT IN (WAITFOR, BROKER_RECEIVE_WAITFOR);查看数据库文件大小和剩余空间SELECT database_id, file_id, name, physical_name, size * 8 / 1024 AS SizeMB, growth * 8 / 1024 AS GrowthMB, max_size FROM sys.master_files WHERE database_id DB_ID(U8Data);查看近期最耗资源的查询SELECT TOP 10 total_worker_time / execution_count AS avg_cpu_time, total_elapsed_time / execution_count AS avg_elapsed_time, total_logical_reads / execution_count AS avg_logical_reads, execution_count, SUBSTRING(st.text, (qs.statement_start_offset / 2) 1, ((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(st.text) ELSE qs.statement_end_offset END - qs.statement_start_offset) / 2) 1) AS sql_text FROM sys.dm_exec_query_stats qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st ORDER BY avg_elapsed_time DESC;这几条脚本不需要多高权限有sysadmin或view server state权限就能跑。建议在业务正常时段和业务高峰期各跑一次对比数据定位快慢差异点。我个人在实际操作中的体会是U8性能优化没有一招鲜的办法它更像一个“查漏补缺”的过程。上面这套组合拳打下来绝大多数U8系统的响应速度都会有明显改善。你不需要一次全部做完可以先从索引碎片、SQL Server内存、TempDB这三个点入手效果很快就能看到。做完之后记得定期维护把那些监控脚本做成每周自动跑一次的任务别等问题出现了再救火。
返回列表