SQLSERVER数据库死锁与优化杂谈
原文:
SQLSERVER数据库死锁与优化杂谈
死锁杂谈 当数据库死锁时,SqlServer会释放一个优先级较低的锁,让另一个事务运行;所以,即时去捕捉数据库死锁,是挺不容易的。 如果,数据库死锁比较长时间,那么死锁是可以被捕捉的。 可以用SqlServer活动监视器来查看,哪些进程锁了数据库。 首先打开SqlServer活动监视器,然后可以看到,界面里有进程,查看资源,数据文件I/O,最近消耗大量资源的查询四项。 四项显示内容如下: 进程:在进程里可以看到哪些进程被阻塞,查看属性【阻塞者】可以看到,【阻塞者】的会话ID。 等待资源:等待资源里有一些锁,可以看看那些锁累计等待时间较多。 数据文件I/O:数据文件I/O记录一些数据库MDF,LDF的读写速度。 最近消耗大量资源的查询:记录一些消耗资源较大的SQL查询。 查询进程里被死锁的会话ID,然后执行下面的SQL,进行解锁。 declare @spid int Set @spid = 518 --锁表进程会话ID declare @sql varchar(1000) set @sql=‘kill ‘+cast(@spid as varchar) exec(@sql) 也可以用下面SQL语句查询死锁进程,这样查询死锁进程,定位比较快。 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName from sys.dm_tran_locks where resource_type=‘OBJECT‘ 优化杂谈 最近消耗大量资源的查询也可以用SQL查询。 下面SQL是查询最耗时的前10条SQL语句。 SELECT TOP 10 total_worker_time / 1000 AS [自编译以来执行所用的CPU时间总量(ms-毫秒)],total_elapsed_time/1000 as [完成执行此计划所用的总时间],total_elapsed_time / execution_count/1000 as [平均完成执行此计划所用时间],execution_count as [上次编译以来所执行的次数],creation_time as [编译计划的时间],deqs.total_worker_time / deqs.execution_count / 1000 AS [平均使用CPU时间(ms)],last_execution_time AS [上次开始执行计划的时间],total_physical_reads [编译后在执行期间所执行的物理读取总次数],total_logical_reads/execution_count [平均逻辑读次数],min_worker_time /1000 AS [单次执行期间所用的最小CPU时间(ms)],max_worker_time / 1000 AS [单次执行期间所用的最大 CPU 时间(ms)],SUBSTRING(dest.text,deqs.statement_start_offset / 2 + 1,(CASE WHEN deqs.statement_end_offset = -1 THEN DATALENGTH(dest.text) ELSE deqs.statement_end_offset END - deqs.statement_start_offset) / 2 + 1) AS [执行SQL],dest.text as [完整SQL],db_name(dest.dbid) as [数据库名称],object_name(dest.objectid,dest.dbid) as [对象名称],deqs.plan_handle [查询所属的已编译计划] FROM sys.dm_exec_query_stats deqs WITH(NOLOCK) CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest --平均使用CPU时间降序 ORDER BY (deqs.total_worker_time / deqs.execution_count / 1000) DESC 在SqlServer活动监视器里,查看资源等待。 通常可以看到等待类别是Latch的排在最上面,如下图: Latch 【闩锁】虽然是一种轻量级的锁,但等待的锁越多,肯定越影响数据库性能。 执行下面SQL,查看下哪些Latch比较耗资源。 SELECT * FROM sys.dm_os_latch_stats 查询结果如下图所示: ? 从结果中可以看到各种锁类型的请求的次数,等待时间,最大等待时间(毫秒)。 但这些锁类型都是英文简写,需要使用下面表格查询它们的真实意义。 通过对比表格,我们发现了最消耗资源的ACCESS_METHODS_DATASET_PARENT锁的意义是并发操作时资源访问的锁。那么想降低并发操作,就可以减少ACCESS_METHODS_DATASET_PARENT锁的资源消耗了。 Latch参考网址:https://docs.microsoft.com/en-us/sql/relational-databases/system-dynamic-management-views/sys-dm-os-latch-stats-transact-sql?view=sql-server-2017 Latch class |
Description |
|