SQL参数化查询的另一个理由命中执行计划
2023-06-13 09:14:35 时间
1概述
SQL语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,SQL语句需要编译之后才能运行,所以每一条SQL是需要通过编译器解释才能运行的(在这之间还要做SQL的优化)。而这些步骤都是需要运行成本,所以在数据库中有一个叫做执行计划的东西,编译器会将编译过后的SQL存入执行计划当中,当遇到同样的SQL时,就直接调用执行计划来执行,而不需要再次编译。
通过对上面执行计划的认识,为了提高数据库运行的效率,我们需要尽可能的命中执行计划,这样就可以节省运行时间。
2相关SQL
2.1查看当前数据库中所有的执行计划:
复制代码代码如下:
SQL语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,SQL语句需要编译之后才能运行,所以每一条SQL是需要通过编译器解释才能运行的(在这之间还要做SQL的优化)。而这些步骤都是需要运行成本,所以在数据库中有一个叫做执行计划的东西,编译器会将编译过后的SQL存入执行计划当中,当遇到同样的SQL时,就直接调用执行计划来执行,而不需要再次编译。
通过对上面执行计划的认识,为了提高数据库运行的效率,我们需要尽可能的命中执行计划,这样就可以节省运行时间。
2相关SQL
2.1查看当前数据库中所有的执行计划:
SELECTcp.usecountsAS"使用次数"
,objtypeAS"类型"
,st.[text]AS"SQL文本"
,plan_handleAS"计划句柄"
FROMsys.dm_exec_cached_planscp
CROSSAPPLYsys.dm_exec_sql_text(plan_handle)ASst
WHEREst.textnotlike"%sys%"
2.2删除执行计划
--删除所有计划
DBCCFREEPROCCACHE
2.3测试脚本(创建员工表,并向其插入1000条数据)
IFEXISTS(SELECT*FROMsys.objectsWHEREobject_id=OBJECT_ID(N"[dbo].[Employee]"))
DROPTABLE[dbo].Employee
GO
--人员表
CREATETABLEdbo.Employee
(
idint,
namenvarchar(50)
);
--插入测试数据
DECLARE@IINT=0,@ENDIINT=1000;
WHILE(@I<@ENDI)
BEGIN
SET@I+=1;
INSERTdbo.Employee(id,name)VALUES(@I,"蒋大华"+CAST(@IASNVARCHAR(20)));
END;
3测试执行计划
3.1先执行删除所有执行计划,然后执行SELECT*FROMEmployee,最后查看执行计划(2.1中的查看执行计划脚本)如下图
即SQLSERVER会为每一条SQL建立一个执行计划,并将它缓存起来
3.2再运行一次SQL:SELECT*FROMEmployee,并查看执行计划
可以看到这个计划的重用次数为2,即这个计划被重用了;
3.3修改SQL:SELECT *FROMEmployee(在SELECT后多加一个空格),执行并查看执行计划
结果又新添加一个执行计划,即SQLSERVER认为这是两个不同的SQL语句并分别建立了执行计划;
4重用执行计划——使用参数化查询方法
stringselectCmdText=string.Format(@"SELECT*FROMEmployeeWHEREname="{0}"",”蒋大华1”);
SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString,System.Data.CommandType.Text,selectCmdText,null);
查看执行计划:
stringselectCmdText=string.Format(@"SELECT*FROMEmployeeWHEREname="{0}"",”蒋大华2”);
SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString,System.Data.CommandType.Text,selectCmdText,null);
查看执行计划
此时不需要再准备一个准备的SQL,但还是需要再产生一个执行计划,并缓存下来;
4.2参数化SQL
SqlParameter[]param={newSqlParameter("@name",txtEmployeeName.Text.Trim())};
stringselectCmdText=string.Format(@"SELECT*FROMEmployeeWHEREname=@name");
SQLHelper.ExecuteNonQuery(SQLHelper.DefaulConnectiontString,System.Data.CommandType.Text,selectCmdText,param);
输入参数并执行,然后查看执行计划:
只需要一个准备SQL,然后,输入不同的参数,并执行,再查看执行计划
重用执行计划,perfect...
5总结
总的来说,SQL语句在执行时,会生成执行计划并将它缓存起来,我们可以通过提高使用缓存中的执行计划次数,来减少数据库的压力。而使用参数化的SQL是一个很好的选择,参数化查询的作用不仅只有防止SQL注入,还可以提高缓存中执行计划使用次数。
相关文章
- DBA命令速查1:查看SQL的执行计划
- python批量执行sql语句_python jdbc
- Spark SQL报错:org.apache.spark.sql.catalyst.errors.package$TreeNodeException 排查记录
- 2023-01-03:超过5名学生的课。编写一个SQL查询来报告 至少有5个学生 的所有班级,返回结果不限顺序。请问sql语句如
- MySQL操作:执行SQL语句(mysql执行sql语句)
- Oracle 日期SQL:超简单查询技巧(oracle日期sql)
- 查询 MySQL查询:从SQL语句中构建你的查询(sql语句mysql)
- MSSQL导出SQL文件的简易方法(mssql导出sql文件)
- ?Redis不支持SQL,抓紧利用其强大的性能吧(redis支持sql吗)
- 语句执行记录MySQL 查看SQL语句执行记录(mysql查看sql)
- MySQL日志跟踪:管理SQL查询性能(mysql跟踪sql语句)
- 优化Oracle数据库SQL优化实践指南(oracle执行sql)
- 如何优化SQL访问Oracle数据库?(sql访问oracle)
- 如何使用MySQL定时自动执行SQL语句(mysql定时执行sql)
- Orcle 解决SQL查询问题的神器(.sql oracle)
- 示例一步一示例,Oracle减一年SQL技术指南(Oracle减一年sql)
- 实现数据库优化Oracle中利用SQL语句实现数据库性能优化(oracle中执行sql)
- 查询Oracle中SQL语句查看显示报表(oracle中sql显示)
- 的order byOracle SQL中的Order By语法实现的排序(oracle中sql中)
- Oracle和SQL调试精准定位问题所在(oracle、sql调试)
- 掌握Oracle SQL写法,激发你的SQL能力(oracle sql写法)
- SQLServer中用T—SQL命令查询一个数据库中有哪些表的sql语句
- 探讨:Oracle数据库查看一个进程是如何执行相关的实际SQL语句