凭证过账慢的原因及解决办法原创
金蝶云社区-战斗的凯文
战斗的凯文
22人赞赏了该文章 348次浏览 未经作者许可,禁止转载编辑于2024年04月12日 15:03:43
        凭证过账(调整期凭证过账,以下简称过账)慢,如果当期凭证数量少于1万的话,一般是过账相关的SQL语句执行耗时长引起的,如果凭证数量大,如超过1万,有可能是网控耗时过长引起的。如果查询发现当前凭证数量并不大,则可排除网控的原因。
        对于SQL语句执行耗时长的原因,一方面可能是列锁导致,也有可能是数据碎片大索引效率低引起。可以用
DBCC SHOWCONTIG(表名)来查询指定表的碎片情况,其中以下相关表和过账有关:
dbcc showcontig(T_GL_BALANCE)
dbcc showcontig(T_GL_BALANCEQTY)
dbcc showcontig(T_GL_BALANCEADJUST)
dbcc showcontig(T_GL_BALANCEQTYADJUST)
dbcc showcontig(T_GL_Voucher)
dbcc showcontig(T_GL_VoucherENTRY)
如下图所示:

image.png

如发现扫描密度百分比较低(一般建议保持90%以上),建议用下面的脚本重建一下相关表的索引,以优化碎片:
Alter index all on T_GL_BALANCE rebuild;
Alter index all on T_GL_BALANCEQTY rebuild;
Alter index all on T_GL_BALANCEADJUST rebuild;
Alter index all on T_GL_BALANCEQTYADJUST rebuild;

执行完索引重建脚本的碎片情况,如下:
image.png

        建议定期执行【管理中心-》数据中心列表-》升级-》数据库优化】,以保持数据库索引效率。此处是对整个账套中所有物理表做索引重建,耗时较长,请在空闲时段,如下班后或深夜进行,以免影响正常工作。

        

        如检查发现上述指标正常,可以用以下脚本查询死锁情况:

SELECT t1.resource_type AS [锁类型], DB_NAME(resource_database_id) AS [数据库名],
t1.resource_associated_entity_id AS [阻塞资源对象],
t1.resource_description as [资源描述信息], t1.request_mode AS [请求的锁], 
t1.request_session_id AS [等待会话], t2.wait_duration_ms AS [等待时间],       
(SELECT [text] FROM sys.dm_exec_requests AS r WITH (NOLOCK)                      
    CROSS APPLY sys.dm_exec_sql_text(r.[sql_handle]) 
    WHERE r.session_id = t1.request_session_id
) AS [等待会话执行的批SQL],
(SELECT SUBSTRING(qt.[text],r.statement_start_offset/2, 
        (CASE WHEN r.statement_end_offset = -1 
        THEN LEN(CONVERT(nvarchar(max), qt.[text])) * 2 
        ELSE r.statement_end_offset END )/2) 
    FROM sys.dm_exec_requests AS r WITH (NOLOCK)
    CROSS APPLY sys.dm_exec_sql_text(r.[sql_handle]) AS qt
    WHERE r.session_id = t1.request_session_id
) AS [等待会话执行的SQL],                    
t2.blocking_session_id AS [阻塞会话],                                        
(SELECT [text] FROM sys.sysprocesses AS p                                       
    CROSS APPLY sys.dm_exec_sql_text(p.[sql_handle]) 
    WHERE p.spid = t2.blocking_session_id
) AS [阻塞会话执行的批SQL]
FROM sys.dm_tran_locks AS t1 WITH (NOLOCK)
INNER JOIN sys.dm_os_waiting_tasks AS t2 WITH (NOLOCK)
ON t1.lock_owner_address = t2.resource_address OPTION (RECOMPILE);
        
如存在死锁,长时间不释放资源,将导致相关的功能卡死,此时可以一下语句【杀死】发生死锁的进程,强制释放资源:
KILL 进程ID
        为防止死锁出现,建议将服务器的【最大并行度】设置为1,具体如下图:

image.png

    

图标赞 22
22人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!