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 数 ...
随机推荐
- 【算法笔记】B1005 继续(3n+1)猜想+sort()用法
1005 继续(3n+1)猜想 (25 分) 卡拉兹(Callatz)猜想已经在1001中给出了描述.在这个题目里,情况稍微有些复杂. 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程 ...
- HDU - 1525 博弈 暴力分析
先来看看比较显然的几个局面 (a,0) 先手必败 (a,a) 先手必胜 (a,ak) 先手必胜 (a,ak+r),k>1 先手必胜,因为先手有主动权把(a,r)让给后手或留给自己 对于开局(a, ...
- flex布局在ios8上的兼容性问题
最近在做项目时,使用到了flex布局.其他ios版本都还好,唯独在ios8上遇到了flex布局没起作用的问题.后来经过研究才发现,safari使用的是webkit内核,在ios8上需要单独加一下兼容才 ...
- PIE SDK栅格生成等值线、面
1.算法功能简介 等值线图能直观地展示数据的变化趋势,是众多领域展示成果的重要图建之一,被广泛应用于石油勘探.矿物开采.气象预报等众多领域.等值线的绘制是指从大量采样数据中提取出具有相同值的点的信 ...
- PIE SDK地图鹰眼图
鹰眼图,是GIS的一个基本功能,在鹰眼图上可以像从空中俯视一样查看地图框中所显示的地图在整个图中的位置,是对全局地图的一种概述表达,能够起到很好的空间提示和导航的作用.网上有很多Arcengine 二 ...
- my31_MGR单写模式压测以及对比普通从库记录
场景MGR单写模式三节点,db46写节点,db47/db48为读节点工具sysbencn.压测15个小时,db46上18线程纯写,12线程oltp混合测试,db48上12线程select在压测2个小时 ...
- linux 卡在进度条进不去解决办法之一
centos为例 一, 如下: 如果这个地方卡住了的话也许是你上次改了passwd文件,这个是其中一个情况. 如果刚刚开机就卡住了或者怎么卡住了的话在开机的读条时候摁esc显示读取的进程,根据显示的错 ...
- Lua初探
官方网站:http://www.lua.org/ 三方模块:https://luarocks.org/ 介绍安装luarocks语法注释标示符关键字全局变量数据类型变量赋值索引循环流程控制函数可变 ...
- 微博关系服务与Redis的故事
http://www.infoq.com/cn/articles/weibo-relation-service-with-redis?utm_source=articles_about_Redis&a ...
- TOJ 1717 WOJ
描述 Alex likes solving problems on WOJ (http://acm.whu.edu.cn/oak). As we all know, a beautiful ballo ...