博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SQL参数化查询的另一个理由——命中执行计划
阅读量:5760 次
发布时间:2019-06-18

本文共 2364 字,大约阅读时间需要 7 分钟。

1概述

    SQL语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,SQL语句需要编译之后才能运行,所以每一条SQL是需要通过编译器解释才能运行的(在这之间还要做SQL的优化)。而这些步骤都是需要运行成本,所以在数据库中有一个叫做执行计划的东西,编译器会将编译过后的SQL存入执行计划当中,当遇到同样的SQL时,就直接调用执行计划来执行,而不需要再次编译。 

    通过对上面执行计划的认识,为了提高数据库运行的效率,我们需要尽可能的命中执行计划,这样就可以节省运行时间。
2相关SQL

2.1查看当前数据库中所有的执行计划:

View Code
SELECT cp.usecounts AS '使用次数'            ,objtype AS '类型'            ,st.[text] AS 'SQL文本'        ,plan_handle    AS '计划句柄'        FROM sys.dm_exec_cached_plans cpCROSS APPLY sys.dm_exec_sql_text(plan_handle) AS stWHERE st.text not like '%sys%'

2.2删除执行计划

View Code
--删除所有计划   DBCC FREEPROCCACHE

2.3测试脚本(创建员工表,并向其插入1000条数据)

View Code
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]'))DROP TABLE [dbo].EmployeeGO--人员表CREATE TABLE dbo.Employee(    id int,    name nvarchar(50));--插入测试数据DECLARE @I INT=0,@ENDI INT=1000;WHILE(@I<@ENDI)BEGIN    SET @I+=1;    INSERT dbo.Employee(id,name) VALUES(@I,'蒋大华'+CAST(@I AS NVARCHAR(20)));END;

3测试执行计划

3.1 先执行删除所有执行计划,然后执行SELECT * FROM Employee ,最后查看执行计划(2.1中的查看执行计划脚本)如下图

   即SQL SERVER会为每一条SQL建立一个执行计划,并将它缓存起来

3.2 再运行一次SQL: SELECT * FROM Employee,并查看执行计划

     可以看到这个计划的重用次数为2,即这个计划被重用了;

3.3 修改SQL:SELECT  * FROM Employee(在SELECT后多加一个空格),执行并查看执行计划

     结果又新添加一个执行计划,即SQL SERVER认为这是两个不同的SQL语句并分别建立了执行计划;

4重用执行计划——使用参数化查询方法

4.1 未参数化SQL

string selectCmdText = string.Format(@"SELECT * FROM Employee WHERE name='{0}'",” 蒋大华1”);SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString, System.Data.CommandType.Text, selectCmdText, null);

     查看执行计划:

    即当执行一个未参数化SQL时,SQL SERVER需要先将其转换成一个参数SQL并执行它。一共需要两执行计划

    然后再执行下面的代码(查询的条件变了)

string selectCmdText = string.Format(@"SELECT * FROM Employee WHERE name='{0}'",” 蒋大华2”);     SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString, System.Data.CommandType.Text, selectCmdText, null);

    查看执行计划

    此时不需要再准备一个准备的SQL,但还是需要再产生一个执行计划,并缓存下来;

4.2 参数化SQL

SqlParameter[] param = { new SqlParameter("@name", txtEmployeeName.Text.Trim()) };string selectCmdText = string.Format(@"SELECT * FROM Employee WHERE name=@name");SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString, System.Data.CommandType.Text, selectCmdText, param);

输入参数并执行,然后查看执行计划:

只需要一个准备SQL,然后,输入不同的参数,并执行,再查看执行计划

重用执行计划,perfect...

5总结

总的来说,SQL语句在执行时,会生成执行计划并将它缓存起来,我们可以通过提高使用缓存中的执行计划次数,来减少数据库的压力。而使用参数化的SQL是一个很好的选择,参数化查询的作用不仅只有防止SQL注入,还可以提高缓存中执行计划使用次数。

转载于:https://www.cnblogs.com/dataadapter/archive/2012/08/02/2620711.html

你可能感兴趣的文章
JS基础-DOM Node节点
查看>>
docker 运行 go语言二进制程序
查看>>
Oracle 备份与恢复学习笔记(5_1)
查看>>
Oracle 备份与恢复学习笔记(14)
查看>>
存储学习之--StarWind高级配置(设置Client访问规则)
查看>>
分布式配置中心disconf第一部(基本介绍)
查看>>
httpd2.4的新特性、以及基本应用
查看>>
iOS为汉字添加各种字体
查看>>
SQL 替换字符串
查看>>
Linux 如何登陆root
查看>>
支付宝支付源码
查看>>
wps4linux在opensuse13.2 x86_64系统下依赖包安装
查看>>
快速构建Windows 8风格应用6-GridView数据控件
查看>>
关闭Debian防火墙
查看>>
阿里百川码力APP监控 来了!
查看>>
android uses-feature导致设备在Android Market搜不到你的应用
查看>>
模仿UC等软件启动画面加载时闪烁点的样式
查看>>
在PHP中使用全局变量的几种方法
查看>>
我的友情链接
查看>>
git常用命令
查看>>