今天测试反应问题,性能测试环境一个脚本执行了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语句的优化过程的更多相关文章

  1. sql server delete语句

    delete语句 --DELETE 语句用于删除表中的行 语法:delete from 表名称 where 列名称 = 值 --可以在不删除表的情况下删除所有的行.这意味着表的结构.属性和索引都是完整 ...

  2. 如何判断一条sql(update,delete)语句是否执行成功

    如何判断一条sql(update,delete)语句是否执行成功 catch  (SQLException    e)  {  }  catch不到错误应该就成功了.   ============== ...

  3. 记一次sql server 2005访问http接口,并解析json的过程

    记一次sql server 2005访问http接口,并解析json的过程  JSON解析官方网站:https://www.red-gate.com/simple-talk/sql/t-sql-pro ...

  4. 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?

    如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集?(2006-12-14 09:25:36) 与这个问题具有相同性质的其他描述还包括:如何 ...

  5. SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条

    SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条 SELECT Id,[Title],[Content],[Image] FROM ( SELECT ROW_NUMBER( ...

  6. SQL Server UPDATE语句的用法详解

    SQL Server UPDATE语句用于更新数据,下面就为您详细介绍SQL Server UPDATE语句语法方面的知识,希望可以让您对SQL Server UPDATE语句有更多的了解. 现实应用 ...

  7. SQL Server中语句的自动参数化

    原文:SQL Server中语句的自动参数化 use master go if exists(select * from sys.databases where name = 'test') drop ...

  8. SQL Server 聚合函数算法优化技巧

    Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值 ...

  9. Sql Server来龙去脉系列之三 查询过程跟踪

    我们在读写数据库文件时,当文件被读.写或者出现错误时,这些过程活动都会触发一些运行时事件.从一个用户角度来看,有些时候会关注这些事件,特别是我们调试.审核.服务维护.例如,当数据库错误出现.列数据被更 ...

随机推荐

  1. Mybatis-学习笔记(5)动态SQL

    1.Mybatis采用功能强大的基于ONGL的表达式来完成动态SQL. 2.ONGL常用的元素有: 1>if <if test="id != null "> an ...

  2. 在SSIS包中使用 Checkpoint从失败处重新启动包[转]

    使用SSIS做ETL的过程中会遇到各种各样的错误,对于一些大数据量的Job失败以后我们不希望重新运行,因为重新运行的时间开销是非常大的,我们只希望从失败的部分开始运行,这样可以省去很多的时间. SSI ...

  3. uboot常用命令

    一. 常用简单命令 1.1. help命令 a. 帮助查看其他命令的使用方法,类型linux下man b. 示例: help help x210 # help help help [command . ...

  4. Mysql中explain作用详解

    一.MYSQL的索引 1.索引(Index):帮助Mysql高效获取数据的一种数据结构.用于提高查找效率,可以比作字典.可以简单理解为排好序的快速查找的数据结构.2.索引的作用:便于查询和排序(所以添 ...

  5. tensorflow学习笔记四----------构造线性回归模型

    首先通过构造随机数,模拟数据. import numpy as np import tensorflow as tf import matplotlib.pyplot as plt # 随机生成100 ...

  6. 源码编译Redis Desktop Manager | 懒人屋

    原文:源码编译Redis Desktop Manager | 懒人屋 源码编译Redis Desktop Manager  2.3k  字    10  分钟    2019-10-10 文章背景 本 ...

  7. 初学ctypes:打开进程并返回相关信息

    直接上代码: 1. my_debugger_defines.py 定义相关结构体(在后面创建进程及返回信息时,传参可用到) from ctypes import * # Let's map the M ...

  8. Apache 安装后启动出现的错误

    错误信息 1: configure: error: APR not found 解决方法:yum install apr* -y 错误信息 2:httpd: apr_sockaddr_info_get ...

  9. linux下的数据备份工具rsync讲解

    linux下的数据备份工具 rsync(remote sync 远程同步)   名词解释: sync(Synchronize,即“同步”)为UNIX操作系统的标准系统调用,功能为将内核文件系统缓冲区的 ...

  10. 17.Linux-CentOS系统OpenStack-Keystone同步数据库时报错

    问题描述:在同步Keystone数据库时报以下错误[root@controller ~]# su -s /bin/sh -c "keystone-manage db_sync" k ...