关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » 网站维护 »如何用参数化SQL语句污染你的计划缓存

    如何用参数化SQL语句污染你的计划缓存

    2015-09-14 00:00:00 出处:ITJS
    分享

    你的SQL语句的参数化总是个好想法。使用参数化SQL语句你不会污染你的计划缓存——错!!!在该文里我想向你展示下用参数化SQL语句就可以污染你的计划缓存,这是非常简单的!

    ADO.NET-AddWithValue

    ADO.NET是实现像SQL Server关系数据库数据访问的.NET框架的组成——有一些严重的副作用。不要误解我——只要你正确使用,ADO.NET一直很棒。你马上就会看到,它很容易被错误使用。我们来看下面实现SQL语句执行的C#代码。

    for (int i = 1; i <= 100; i++) {    val += i.ToString();     cmd = new SqlCommand(       "SELECT * FROM Sales.SalesOrderDetail WHERE CarrierTrackingNumber = @CarrierTrackingNumber",        cnn);    cmd.Parameters.AddWithValue("@CarrierTrackingNumber", val);    SqlDataReader reader = cmd.ExecuteReader();    reader.Close(); } 

    我们是聪明的开发者,因此SQL语句本身被参数化,因为ADO.NET框架是地球上最棒的框架,我们使用System.Data.SqlClient.SqlParameterCollection类的AddWithValue方法来提供实际的参数值。我在WHLIE循环里运行那个SQL语句100次,总用不同长度赋予参数值。在Sales.SalesOrderDetail表里CarrierTrackingNumber列定义为NVARCHAR(25)。因此我们可以在基于我们提供的不同字符长度上有上至25个不同数据类型的参数。现在让我们检查下我们SQL语句执行后的计划缓存。

    1 SELECT 2     st.text, 3     cp.* 4 FROM sys.dm_exec_cached_plans cp 5 CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st 6 GO 

    现在事情变得有点疯狂:在计划缓存里我们存储了100个不同的执行计划!

    对于每个可能的数据类型参数都有1个执行计划——即使当数据类型是NVACHAR(25)。AddWithValue方法非常,非常邪恶:基于你提供的参数值派生出数据类型。永远不要使用它!

    ADO.NET – SqlDbType.VarChar

    因为从我们的错误中我们学到了,现在我们知道ADO.NET的AddWithValue方法的副作用——我们不再用它。现在让我们重写我们的C#程序代码,如下所示定义一个显示的参数数据类型:

     

    for (int i = 1; i <= 100; i++) {    val += i.ToString();     cmd = new SqlCommand(       "SELECT * FROM Sales.SalesOrderDetail WHERE CarrierTrackingNumber = @CarrierTrackingNumber",       cnn);    cmd.Parameters.Add(new SqlParameter("@CarrierTrackingNumber", SqlDbType.VarChar));    cmd.Parameters["@CarrierTrackingNumber"].Value = val;    SqlDataReader reader = cmd.ExecuteReader();    reader.Close(); } 

    从代码里你可以看到,ADO.NET现在不能派生参数数据类型了,因为我们已经指定了SqlDbType.Varchar数据类型。让我们再次执行这个SQL语句100次并再次检查下计划缓存:

    没有啥改变。问题还是一样:在计划缓存里我们还有100个不一样的的执行计划。现在的问题是ADO.NET只强制数据类型(SqlDbType.VarChar),但不是数据类型的"长度"。有100个不同的长度在计划缓存里你就有100个不同的执行计划。

    假如你在你的ADO.NET代码里显式指定参数数据类型,你也要指定它的长度!现在我们来看下一些修正的C#代码。

    for (int i = 1; i <= 100; i++) {    val += i.ToString();     cmd = new SqlCommand(       "SELECT * FROM Sales.SalesOrderDetail WHERE CarrierTrackingNumber = @CarrierTrackingNumber",       cnn);    cmd.Parameters.Add(new SqlParameter("@CarrierTrackingNumber", SqlDbType.VarChar, 100));    cmd.Parameters["@CarrierTrackingNumber"].Value = val;    SqlDataReader reader = cmd.ExecuteReader();    reader.Close(); } 

    这次我也指定了数据类型的长度——这里是100,现在当我们再次执行SQL语句100次时,最后我们在计划缓存里以1个执行计划且重用了100次来完美收工。这是从SQL Server角度的最终目标。

    小结

    寓意:ADO.NET是个很棒的数据访问框架,它提供你有用的功能(例如AddWithValue方法),当从SQL Server角度来说你真的要考虑下你在做什么。当你使用参数化SQL语句时,你要尽量显式:你必须地冠以参数值的实际数据类型,还有你想要的获得数据类型长度。

    感谢关注!

    注:此文章为WoodyTu学习MS SQL技术,收集整理相关文档撰写,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出此文链接!

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    DEDECMS织梦v5.7保存当前栏目更改时失败,请检查你的输入资料是否存在问题!

    算力行业有哪些权威的行业网站?

    解决帝国CMS搜索模板不支持灵动标签的方法支持ecms7.5

    2026 年主流人力资源管理系统深度评测:7 大厂商横评,全栈一体化标杆领跑全行业

    WPS Office 原生登陆 Windows on ARM,全链路重构告别模拟时代

    赛富时与雪花发布财报,市场聚焦人工智能对软件行业的影响

    产品力即口碑:WPS for Pad印尼免费总榜第一,获多国用户五星好评

    Windows 11 通过cmd终端wmic命令查看笔记本电脑硬件配置信息

    Java依然优秀的9个理由

    彻底关闭Windows 11自动更新的方法之一:修改注册表,禁止自动更新500年!

    IT头条

    长鑫科技一签能赚多少?五家理财公司“打新”或浮盈近2亿元

    00:15

    Goodram RIVAL和Goodram PRO——波兰制造商推出两个新内存品牌

    23:05

    Cignal AI:到2030年,CPO年部署端口数超3000万个

    15:47

    投资10亿欧元,TikTok在芬兰建设新数据中心

    11:39

    Veeam 2026年数据信任与韧性报告:对从网络事件中恢复的能力充满信心

    11:14

    技术热点

    windows 7系统打开IE浏览器提示“禁用的加载项,网页内容无法显

    SQL Server identity列,美中不足之处

    Android UI控件系列:Toast(提示)

    提高windows7系统运行速度的方法

    修改windows 7系统日志存放路径将其放在指定的位置

    windows 7创建宽带连接的详细图文教程

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。