SQL结构化查询的第二个理由 命中落实计划
发布时间:2023-07-27 14:25:11 所属栏目:MsSql教程 来源:
导读:概述
sql语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,sql语句需要编译之后才能运行,所以每一条sql是需要通过编译器解释才能运行的(在这之间还要做sql的优化)。而这些步骤都
sql语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,sql语句需要编译之后才能运行,所以每一条sql是需要通过编译器解释才能运行的(在这之间还要做sql的优化)。而这些步骤都
概述 sql语言的本质就是一串伪代码,表达的是做什么,而不是怎么做的意思。如其它语言一样,sql语句需要编译之后才能运行,所以每一条sql是需要通过编译器解释才能运行的(在这之间还要做sql的优化)。而这些步骤都是需要运行成本,所以在数据库中有一个叫做执行计划的东西,编译器会将编译过后的sql存入执行计划当中,当遇到同样的sql时,就直接调用执行计划来执行,而不需要再次编译。 通过对上面执行计划的认识,为了提高数据库运行的效率,我们需要尽可能的命中执行计划,这样就可以节省运行时间。 2相关sql 2.1查看当前数据库中所有的执行计划: 代码如下: SELECT cp.usecounts AS '使用次数' ,objtype AS '类型' ,st.[text] AS 'sql文本' ,plan_handle AS '计划句柄' FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st WHERE st.text not like '%sys%' 2.2删除执行计划 代码如下: --删除所有计划 DBCC FREEPROCCACHE 2.3测试脚本(创建员工表,并向其插入1000条数据) 代码如下: IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Employee]')) DROP TABLE [dbo].Employee GO --人员表 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,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,param); 输入参数并执行,然后查看执行计划: 只需要一个准备sql,然后,输入不同的参数,并执行,再查看执行计划 重用执行计划,perfect... 5总结 总的来说,sql语句在执行时,会生成执行计划并将它缓存起来,我们可以通过提高使用缓存中的执行计划次数,来减少数据库的压力。而使用参数化的sql是一个很好的选择,参数化查询的作用不仅只有防止sql注入,还可以提高缓存中执行计划使用次数。 (编辑:聊城站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
推荐文章
站长推荐