MSSQL的SQL语句独立执行消耗与线上执行消耗差异
环境: SQL Server 2012
疑问:同样的一条语句,使用Profile跟踪出来的消耗与单独拿出来执行的消耗存在非常大的差距
语句如下:
declare @str nvarchar(max) ; set @str = ' SELECT *
FROM t1
WHERE 1 = 1
and flag != 0
and t1.isRestore=0
and t1.flag = @flag
and t1.mebId=@mebId
and addSubBusType in ( select ListValue from dbo.fn_splitstr(@inAddSubBusType,'','') )
and t1.UsedBeginTime <= @usedBeginTimeLessThenOrEqual
and (convert(datetime,convert(varchar,t1.UsedEndTime,112),112)+1-1.0/3600/24) >= @usedEndTimeMoreThenOrEqual
and (select count(0)
from t3
where t3.configid=t1ConfigID
and t3.begintime <= @checkInDateInLimitDateRange_1
and @checkInDateInLimitDateRange_2<=(convert(datetime,convert(varchar,t3.endtime,112),112)+1-1.0/3600/24))<=0
and UsedWeekID in ( select ListValue from dbo.fn_splitstr(@inWeekIdsSql,'','') ) ' exec sp_executesql @str, N' @flag int, @mebId int, @inAddSubBusType nvarchar(max), @usedBeginTimeLessThenOrEqual datetime, @usedEndTimeMoreThenOrEqual datetime, @checkInDateInLimitDateRange_1 datetime, @checkInDateInLimitDateRange_2 datetime, @inWeekIdsSql nvarchar(max)',
@flag=1,
@mebId=222144787,
@inAddSubBusType='0, 11, 12, 52',
@usedBeginTimeLessThenOrEqual='2017-06-13 00:00:00',
@usedEndTimeMoreThenOrEqual='2017-06-13 00:00:00',
@checkInDateInLimitDateRange_1='2017-06-13 00:00:00',
@checkInDateInLimitDateRange_2='2017-06-13 00:00:00',
@inWeekIdsSql='2, 1000001, 1000003, 1000004, 3000006, 3000007, 3000008'
备注:先不要吐槽以下2个条件的写法
(convert(datetime,convert(varchar,t1.UsedEndTime,112),112)+1-1.0/3600/24) >= @usedEndTimeMoreThenOrEqual
@checkInDateInLimitDateRange_2<=(convert(datetime,convert(varchar,t3.endtime,112),112)+1-1.0/3600/24)
使用Profile跟踪出来的语句的执行消耗如下:
select top 1000 TextData
, Reads
, Writes
, CPU --单位:毫秒
, Duration Duration --Duration单位:微秒
, HostName
, ClientProcessID
, ApplicationName
, LoginName
, SPID
, StartTime
, EndTime
, ServerName
, ObjectName
, DatabaseName
, RowCounts
from ::fn_trace_gettable('~path\ProfileMonitor_20170614-15.trc',default)
where LoginName = 'xxxx'
order by StartTime desc
Profile跟踪出来对CPU的消耗非常高,这样的一条语句,并发非常高,造成了服务器几乎卡死
把语句拿出来单独执行,查看消耗情况
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。 SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。 SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。 (15 行受影响)
表 't3'。扫描计数 15,逻辑读取 38 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '#B63AB884'。扫描计数 1,逻辑读取 15 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Workfile'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 'Worktable'。扫描计数 0,逻辑读取 0 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't2'。扫描计数 1,逻辑读取 4 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 't4'。扫描计数 15,逻辑读取 15 次,物理读取 0 次,预读 0 次,lob 逻辑读取 46 次,lob 物理读取 0 次,lob 预读 0 次。
表 't1'。扫描计数 1,逻辑读取 71 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。
表 '#B72EDCBD'。扫描计数 1,逻辑读取 1 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。 (1 行受影响) SQL Server 执行时间:
CPU 时间 = 15 毫秒,占用时间 = 59 毫秒。 SQL Server 执行时间:
CPU 时间 = 15 毫秒,占用时间 = 60 毫秒。
SQL Server 分析和编译时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。 SQL Server 执行时间:
CPU 时间 = 0 毫秒,占用时间 = 0 毫秒。
执行计划如下:
该用索引的地方已经使用了索引,而且消耗也不像Profile里跟踪出来的那么高。是什么原因造成在线上的程序中运行时消耗如此之大?
找不到原因, 只好试着把原来的执行缓存清除掉,让其重新生成
select decp.plan_handle
, decp.usecounts
, dest.[text]
, deqp.query_plan
from sys.dm_exec_cached_plans decp
cross apply sys.dm_exec_sql_text(decp.plan_handle) dest
cross apply sys.dm_exec_query_plan(decp.plan_handle) deqp
where dest.[text] like '%@flag%'
order by usecounts desc
根据以上语句得到的plan_handle,再执行
dbcc freeproccache(0x0600070057A88E01B0BC9E0D2600000001000000000000000000000000000000000000000000000000000000)
plan_handle的值为0x0600070057A88E01B0BC9E0D2600000001000000000000000000000000000000000000000000000000000000,之后再观察Profile,竟然没有发现没有跟踪到这条语句了。把Duration的值调整为10ms,之后,跟踪到的结果是这样的
select top 1000 TextData
, Reads
, Writes
, CPU --单位:毫秒
, Duration/1000 Duration --Duration单位:微秒;Duration/1000单位:毫秒
, StartTime
, EndTime
, ServerName
, ObjectName
, DatabaseName
, RowCounts
from ::fn_trace_gettable('~path\ProfileMonitor_20170620-15.trc',default)
where TextData not like '%sp_prepare%'
order by StartTime desc
Reads虽然高,但是CPU却下降非常明显,而且,执行计划也发生了改变
总结:当发现理想的执行效果与实际的执行效果存在很大差异的时候,可能就得要先确认缓存的执行计划是不是正确的。若不是,就需要做一下清空处理了。注意,在生产环境中,不能直接执行
dbcc freeporccache ;
否则会出现严重的性能问题。
以上,如有错谬,请不吝指正。
MSSQL的SQL语句独立执行消耗与线上执行消耗差异的更多相关文章
- easyui datagrid 禁止选中行 EF的增删改查(转载) C# 获取用户IP地址(转载) MVC EF 执行SQL语句(转载) 在EF中执行SQL语句(转载) EF中使用SQL语句或存储过程 .net MVC使用Session验证用户登录 PowerDesigner 参照完整性约束(转载)
easyui datagrid 禁止选中行 没有找到可以直接禁止的属性,但是找到两个间接禁止的方式. 方式一: //onClickRow: function (rowIndex, rowData) ...
- [MSSQL]从SQL语句的角度 提高数据库的访问性能
1.什么是执行计划?执行计划是依赖于什么信息. 2. 统一SQL语句的写法减少解析开销 3. 减少SQL语句的嵌套 4. 使用“临时表”暂存中间结果 5. OLTP系统SQL语句必须采用绑定变量 6. ...
- php-mysql 问题笔记一——在命令行中可以执行的sql语句,无法从php页面页面执行!
我的情况: 1.由于外键较多,插入数据时,提前关闭外键(SET FOREIGN_KEY_CHECKS=0). 2.所使用的sql语句中,有外键绑定到其他表中,所以无法从php页面插入. 原因分析: S ...
- 腾讯一面问我SQL语句中where条件为什么写上1=1
目录 where后面加"1=1″还是不加 不用where 1=1 在多条件查询的困惑 使用where 1=1 的好处 使用where 1=1 的坏处 where后面加"1=1″还是 ...
- SQL 语句中 where 条件后 写上1=1 的意思
这段代码应该是由程序(例如Java)中生成的,where条件中 1=1 之后的条件是通过 if 块动态变化的.例如: String sql="select * from table_nam ...
- MySQL线上执行大事务或锁表操作
前提 在线执行一些大事务或锁表操作(给某个核心级表加一列或者执行修改操作),此时不但主库从库要长时间锁表,主从延迟也会变大.未避免大事务sql对整个集群产生影响,,我们希望一条SQL语句只在Maste ...
- mssql 判断sql语句的执行效率语句
SET STATISTICS io ONSET STATISTICS time ONgo--========此处为sql代码段=============== select zxbh from t_yr ...
- mssql 常用SQL语句或函数
按 OrderDate 的顺序计算 SalesOrderHeader 表中所有行的行号,并只返回行 50 到 60(含). WITH OrderedOrders AS ( SELECT SalesOr ...
- sqlcmd 执行SQL语句或没有足够的内存来执行脚本
win+r命令提示框里面输入cmd sqlcmd -S . -U username -P password -d database -i url -S 数据库地址 -U 登录名称 -P 密码 -d 数 ...
随机推荐
- Windows10 下安装配置IIS + MySQL5.7.19 + nginx1.12.1 + php7.1.7
环境: VMWare Workstation Player12 Windows10 Pro x64 一.安装系统 vmware 会采用 fast install 方式很快装完,无需配置什么. 二.配置 ...
- 求一个区间里的一个x,这个x与这区间里面的所有数都互质
链接:https://ac.nowcoder.com/acm/contest/301/H来源:牛客网 题描述 小乐乐上了一节数学课,数学老师讲的很好,小乐乐听的也如痴如醉. 小乐乐听了老师的讲解,知道 ...
- 最小生成树----prim算法的堆优化
题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M<= ...
- 执行AJAX返回HTML片段中的JavaScript脚本
如果AJAX加载的数据是一个HTML片段,而且这个HTML片段还包含脚本<script>块,那么在你把这数据xmlHttp.responseText用innerHTML方法插入到当前文档一 ...
- 对avalonjs的研究
<!DOCTYPE html> <html> <head> <title>第一个avalon项目</title> <meta char ...
- Q686 重复叠加字符串匹配
给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1. 举个例子,A = "abcd",B = " ...
- 关于在scrapy中使用xpath
1. 还是以虎嗅为例,他给我返回的是一个json格式的json串 2.那么我需要操作的就是把json串转换成我们的字典格式再进行操作 str=json.loads(response.body)['da ...
- CNN Advanced
from sys import path path.append('/home/ustcjing/models/tutorials/image/cifar10/') import cifar10,ci ...
- 谈谈UI设计的6个实用小技巧
从事UI设计的朋友们,肯定知道我们在做UI设计时,其实是可以通过一些小技巧来帮我们设计的界面更加的漂亮.实用.交互性强,用户体验更好.今天的话,上海艾艺在互联网上面搜寻了几个小技巧.在这里跟大家一起来 ...
- 8086实时时钟实验(二)——《x86汇编语言:从实模式到保护模式》读书笔记06
上次我们说了代码,这次我们说说怎样看到实验结果. 首先编译源文件(我的源文件就在当前路径下,a盘和c盘在上一级目录下): nasm -f bin c08_mbr.asm -o c08_mbr.bin ...