设为首页 收藏本站
查看: 960|回复: 0

[经验分享] SQL SERVER中隐式转换的一些细节浅析

[复制链接]
发表于 2017-7-12 19:46:30 | 显示全部楼层 |阅读模式
  其实这是一篇没有技术含量的文章,精通SQL优化的请绕道。这个缘起于在优化一个SQL过程中,同事问了我一个问题,为什么SQL中存在隐式转换,但是执行计划没有变? 我思索了一下,觉得这个问题也有点意思,说不定有些对隐式转换了解得不深入的同学都有此疑问,那么下面结合上下文场景做一个细节方面的解答。
  我们一个系统中使用了ORMLite框架,粗心的开发人员弄出了不少下面这样的SQL语句,都存在隐式转换问题,如下所示,表machine_stop_alarm_msg 的结构如下,字段machine_no、status都为VARCHAR(10),但是下面SQL,传入的变量@P0,@P1都是NVARCHAR(4000)类型。
     DSC0000.png


DECLARE  @P0 nvarchar(4000),@P1 nvarchar(4000); SET @P0='1';SET @P1='K172'; SELECT [recid],[machine_no]    ,[stop_stime]    ,[stop_etime]    ,[status]    ,[memo]    ,[createddate]  FROM machine_stop_alarm_msg t  WHERE 1=1  AND t.status=@P0  AND t.machine_no in(@P1 )  ORDER BY machine_no,    stop_stime ;    

  machine_stop_alarm_msg 表只有一个聚集索引PK_machine_stop_alarm_msg,字段为recid。
   DSC0001.png
    当时我优化的时候,就觉得这个SQL语句存在两个问题:1 缺少索引; 2 存在隐式转换问题。当时创建了下面索引,并要求开发人员修改SQL,避免隐式转换。




CREATE NONCLUSTERED INDEX ix_machine_stop_alarm_msg_n1ON [dbo].[machine_stop_alarm_msg] ([machine_no],[status])INCLUDE ([recid],[stop_stime],[stop_etime],[memo],[createddate])GO  

  在测试环境测试时,我们先不增加这个索引,就出现了下面一个场景,两者都是走聚集索引扫描:
    1: 执行计划走聚集索引扫描(Cluster Index Scan)




SET STATISTICS IO ON;SET STATISTICS TIME ON;DECLARE  @P0 nvarchar(4000),@P1 nvarchar(4000); SET @P0='1';SET @P1='K172';SELECT [recid],[machine_no]    ,[stop_stime]    ,[stop_etime]    ,[status]    ,[memo]    ,[createddate]  FROM machine_stop_alarm_msg t  WHERE 1=1  AND t.status=@P0  AND t.machine_no in(@P1 )  ORDER BY machine_no,    stop_stime ;   SET STATISTICS IO OFF;SET STATISTICS TIME OFF;
   DSC0002.png
   DSC0003.png
  
  2: 执行计划走聚集索引扫描(Cluster Index Scan)  




SET STATISTICS IO ON;SET STATISTICS TIME ON;DECLARE  @P0 VARCHAR(10),@P1 VARCHAR(10); SET @P0='1';SET @P1='K172';SELECT [recid],[machine_no]    ,[stop_stime]    ,[stop_etime]    ,[status]    ,[memo]    ,[createddate]  FROM machine_stop_alarm_msg t  WHERE 1=1  AND t.status=@P0  AND t.machine_no in(@P1 )  ORDER BY machine_no,    stop_stime ;   SET STATISTICS IO OFF;SET STATISTICS TIME OFF;
   DSC0004.png
  
  这里两者的执行计划一样,这个应该很好理解,缺少相关索引,而且发生隐式转换的不是索引所在的字段,那么即使存在隐式转换,它的执行计划是一样的。 这里没有太多要解释的。
  那么我们接下来看看看增加了索引后,两者的实际执行计划。
  
   DSC0005.png
   DSC0006.png
  
  现在同事纠结的就是即使发生了隐式转换,为什么执行计划还是走索引查找(Index Seek)呢? 其实很多人有一个误区,SQL Server当中并不是所有的隐式转换都会导致索引扫描(Index Scan),关于这个请见我这篇博客SQL SERVER中什么情况会导致索引查找变成索引扫描 。也就是说隐式转导致索引扫描也是有条件的。这里不再做展开讲,没有太多意思。另外,我们再来对比一下两者的执行计划。
  
  上面发生隐式转换的SQL的执行计划,多了一个常量扫描(Constant Scan),常量扫描做的工作是根据用户输入的SQL中的常量生成一个行 ,MSDN的介绍如下:
  "The Constant Scan operator introduces one or more constant rows into a query. A Compute Scalar operator is often used after a Constant
  Scan to add columns to a row produced by the Constant Scan operator"
  
  常量扫描会引入一个或者多个常量行到一个查询中;通常情况下紧跟常量扫描的是计算标量运算符,计算标量运算符会为常量扫描运算符产生的行添加列。
   DSC0007.png
  如果你想知道执行计划里面的Expr1004、 Expr1005、Expr1003对应啥,看看执行计划就知道了(其中Expr1003为(62),一开始不明其什么意义,后面咨询了宋大神,才知道62是个flag,意思是等于号)   DSC0008.png
  
  发生隐式转换的SQL还多了一个Nested Loop(Inner Join)操作。另外,即使这两个SQL依然都是索引查找(Index Seek),但是两种的IO开销还是有所区别的。
   DSC0009.png
DSC00010.png


   DSC00011.png   
DSC00012.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393277-1-1.html 上篇帖子: EXPERT FOR SQL SERVER诊断系列--索引 下篇帖子: SQL SERVER 的前世今生--各版本功能对比
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表