记一次SQL Server delete语句的优化过程
今天测试反应问题,性能测试环境一个脚本执行了3个小时没有出结果,期间其他dba已经建立了一些索引但是没有效果。
语句:
DELETE T from License T WHERE exists (select 1 from #i_RollbackTrans r where r.LicenseID= T.LicenseID)
表License数据量4千万
表#i_RollbackTrans数据量5万
最终删除数据量5万
部分执行计划:

可以发现表上有很多索引, 临时表经过distinct之后和索引进行nested loop,问题不大。

通过以下sql查询会话的read write和cpu 变化:
;WITH task_space_usage AS
(
-- SUM alloc/delloc pages
SELECT session_id,
request_id,
SUM(internal_objects_alloc_page_count) AS internal_alloc_pages,
SUM(user_objects_alloc_page_count) AS user_alloc_pages
FROM sys.dm_db_task_space_usage WITH (NOLOCK)
WHERE session_id <> @@SPID
GROUP BY session_id, request_id
)
SELECT
r.session_id
,r.percent_complete
--,r.query_hash
--,r.sql_handle
--,r.plan_handle
,r.start_time
,getdate()
,datediff(ss,r.start_time,getdate()) duration
, DB_NAME(r.database_id) AS dbname
,[Parent Query] = st.text
-- ,[Individual Query] = SUBSTRING (st.text, (r.statement_start_offset/2) + 1,
--((CASE WHEN r.statement_end_offset = -1
--THEN LEN(CONVERT(NVARCHAR(MAX), st.text)) * 2
-- ELSE r.statement_end_offset
-- END - r.statement_start_offset)/2) + 1
,[Individual Query] = SUBSTRING (st.text, (r.statement_start_offset/2),
((CASE WHEN r.statement_end_offset = -1
THEN DATALENGTH(st.text)
ELSE r.statement_end_offset
END - r.statement_start_offset)/2))
,r.wait_type
,r.cpu_time, r.reads, r.writes
,r.blocking_session_id,r.session_id
--,dbo.udf_GetHeadBlocker(r.session_id) AS 'blockChain'
,r.percent_complete ,r.wait_resource,r.status, r.command, r.transaction_isolation_level
,s.host_name, s.login_name
,case when s.program_name like 'SQLAgent - TSQL JobStep%' then
--substring(s.program_name,30,34)
(select name from msdb.dbo.sysjobs where cast(job_id as binary(16)) =
convert(varbinary(16),substring(s.program_name,30,34),1))
else s.program_name
end as program_name
, s.host_process_id, c.client_net_address
--,deqp.query_plan
,blocking_cache.text AS blocking_text
, waitstats.wait_duration_ms
,TSU.internal_alloc_pages * 1.0 / 128 AS [internal object MB space]
,TSU.user_alloc_pages * 1.0 / 128 AS [user object MB space]
FROM sys.dm_exec_requests AS r
left JOIN task_space_usage AS TSU ON TSU.session_id = r.session_id AND TSU.request_id = r.request_id
left JOIN sys.dm_exec_sessions AS s ON s.session_id=r.session_id
left JOIN sys.dm_exec_connections AS c ON s.session_id=c.session_id
LEFT JOIN sys.dm_exec_connections AS blocking ON blocking.session_id = r.blocking_session_id
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS st
OUTER APPLY sys.dm_exec_sql_text(blocking.most_recent_sql_handle) blocking_cache
--OUTER APPLY sys.dm_exec_query_plan(r.plan_handle) deqp
LEFT OUTER JOIN sys.dm_os_waiting_tasks waitstats ON waitstats.session_id = r.session_id
WHERE r.session_id>50
AND r.session_Id NOT IN (@@SPID)
ORDER BY r.cpu_time DESC,r.reads DESC, r.blocking_session_id DESC
GO
观察结果发现,read很少只有300,write到30万,但是执行期间一直没有变化,cpu_time持续增加,会话状态是running并且没有等待事件。
通过分析得出,执行计划查询部分和上面分析一样不存在问题,虽然表上有很多索引,但是删除数据占比表整体数据较少0.1%, 而且writes始终没变化,证明不是阻塞再索引的删除上面。那么是什么消耗cpu_time但是没有任何IO变化?
下面看被表引用的外键关系:

可以看到相当多的外键引用该表,并且是强制检查状态,其中一部分还是自引用。
最终通过临时禁用外键检测,删除,再启用的方式将3个小时没有执行完的sql优化再20分钟完成。
记一次SQL Server delete语句的优化过程的更多相关文章
- sql server delete语句
delete语句 --DELETE 语句用于删除表中的行 语法:delete from 表名称 where 列名称 = 值 --可以在不删除表的情况下删除所有的行.这意味着表的结构.属性和索引都是完整 ...
- 如何判断一条sql(update,delete)语句是否执行成功
如何判断一条sql(update,delete)语句是否执行成功 catch (SQLException e) { } catch不到错误应该就成功了. ============== ...
- 记一次sql server 2005访问http接口,并解析json的过程
记一次sql server 2005访问http接口,并解析json的过程 JSON解析官方网站:https://www.red-gate.com/simple-talk/sql/t-sql-pro ...
- 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?
如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括:如何 ...
- SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条
SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条 SELECT Id,[Title],[Content],[Image] FROM ( SELECT ROW_NUMBER( ...
- SQL Server UPDATE语句的用法详解
SQL Server UPDATE语句用于更新数据,下面就为您详细介绍SQL Server UPDATE语句语法方面的知识,希望可以让您对SQL Server UPDATE语句有更多的了解. 现实应用 ...
- SQL Server中语句的自动参数化
原文:SQL Server中语句的自动参数化 use master go if exists(select * from sys.databases where name = 'test') drop ...
- SQL Server 聚合函数算法优化技巧
Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值 ...
- Sql Server来龙去脉系列之三 查询过程跟踪
我们在读写数据库文件时,当文件被读.写或者出现错误时,这些过程活动都会触发一些运行时事件.从一个用户角度来看,有些时候会关注这些事件,特别是我们调试.审核.服务维护.例如,当数据库错误出现.列数据被更 ...
随机推荐
- Mybatis-学习笔记(3)mapper配置文件
1.mapper配置文件常用的元素 parameterMap已经废弃,老式风格的参数映射. 2.select元素 映射查询语句.#{...}用于预处理语句参数,通过JDBC,这样一个参数在SQL中会由 ...
- java int转Short
使用short(xx) problemMultipleChoiceDO.setExamCount((short)0);//在数据库中是smallint类型
- Python和Js打印心形
看到一行Python写的代码,会用LovePython输出心形: print('\n'.join([''.join([('LovePython'[(x-y)%10]if((x*0.05)**2+(y* ...
- Redis---Redis与Memcached
4.Redis与Memcached 两者都是非关系型内存键值,主要有以下不同: 数据类型 Memcached仅支持字符串类型,而Redis支持五种不同的数据类型,可以更灵活地解决问题. 数据持 ...
- #define 宏实现函数功能可能存在的问题
#define 宏实现函数功能的问题 情形1 #define free_ptr(p) \ if(p) delete p; p = nullptr; 在调用free_ptr(p)的地方展开看这段代码: ...
- 华为云搭建windows+wordpress+xampp
1.如何将本地文件上传至华为云ECS云服务器(Windows系统) 1.1 在本地电脑上,快捷键“WIN+R"打开“运行”中输入“mstsc”,点击确定 1.2 在“远程桌面连接”框点击“ ...
- input check复选框选择后修改<a>标签超链接href
1. 给复选框添加onclick事件 获取标签id <tbody> <c:forEach var="file" items="${files}" ...
- Oracle 赋予指定用户dba权限
指定用户赋权限 1.链接数据库地址,使用ssh登录 2.sudo -i 3.grant dba to 用户名;
- Linux学习--第七天--用户和用户组
用户和用户组 usermod -a -G groupname username // 将已有用户添加到已有用户组 /etc/passwd michael:x:500:500:CentOS:/home/ ...
- Python变量类型及变量
python是解释性语言 什么是解释性语言 就相当于你去饭店,你点了10道菜,他做好1道给你上1道.解释一行,执行一行.速度上不如编译性语言快. 什么是编译性语言 就相当于去饭店吃饭,你点了10道菜, ...