SQL Server中语句的自动参数化

原文:SQL Server中语句的自动参数化


  1. use master
  2. go
  3. if exists(select * from sys.databases where name = ‘test‘)
  4. drop database test
  5. go
  6. --创建数据库
  7. create database test
  8. if exists(select * from sys.tables where name = ‘t‘)
  9. drop table t
  10. go
  11. --1.创建表t
  12. create table t(i int);
  13. --2.添加100000条记录,消耗56秒
  14. declare @i int;
  15. declare @sql varchar(1000);
  16. set @i = 1
  17. set @sql = ‘‘;
  18. while @i <= 100000
  19. begin
  20. set @sql = ‘insert into t values(‘ + cast(@i as varchar) +‘)‘
  21. begin tran
  22. exec(@sql)
  23. commit tran
  24. set @i = @i + 1
  25. end
  26. --3.1查询的统计信息
  27. --但发现没有返回记录
  28. select st.text,
  29. SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
  30. ((CASE qs.statement_end_offset
  31. WHEN -1 THEN DATALENGTH(st.text)
  32. ELSE qs.statement_end_offset
  33. END - qs.statement_start_offset)/2) + 1) AS statement_text,
  34. qs.*
  35. from sys.dm_exec_query_stats qs
  36. cross apply sys.dm_exec_sql_text(qs.sql_handle) st
  37. where cast(st.text as varchar) like ‘%insert into t values%‘
  38. --3.2查询的统计信息
  39. --有返回,说明SQL Server在执行动态生成的语句时,已经参数化了
  40. --execution_count字段的值为100000
  41. select st.text,
  42. SUBSTRING(st.text, (qs.statement_start_offset/2)+1,
  43. ((CASE qs.statement_end_offset
  44. WHEN -1 THEN DATALENGTH(st.text)
  45. ELSE qs.statement_end_offset
  46. END - qs.statement_start_offset)/2) + 1) AS statement_text,
  47. qs.*
  48. from sys.dm_exec_query_stats qs
  49. cross apply sys.dm_exec_sql_text(qs.sql_handle) st
  50. where cast(st.text as varchar) like ‘%insert into%‘
  51. --3.3 查看数据库是否强制参数化
  52. --并没有强制参数化,说明上面是系统自动对语句进行参数化了
  53. select name,
  54. is_parameterization_forced --返回0,说明并没有强制参数
  55. from sys.databases
  56. where name = ‘test‘
  57. --3.4 再次执行后,再次执行3.2后发现,execution_count为100001
  58. insert into t values(100001)
  59. --3.5 这次在语句中加了空格,execution_count为100002
  60. insert into t values( 100002 )
  61. --3.5 这次在语句中加了架构
  62. --返回2条记录,一条为100002,另一个为1
  63. --虽然2条数据的sql_handle、plan_handle都不相同,但是query_hash、query_plan_hash相同
  64. insert into dbo.t values( 100003 )
  65. --3.6 显示缓存的执行计划
  66. --返回2条数据,一条为100002,一个为1
  67. --缓存对象类型为编译计划,对象类型为Prepared
  68. select *
  69. from sys.dm_exec_cached_plans cp
  70. cross apply sys.dm_exec_sql_text(cp.plan_handle) st
  71. where st.text like ‘%insert into%‘

最后总结一下:

1.对于一些比较简单的语句,SQL Server能自动进行参数化,会自动忽略空格。

2.但当语句有不同时,比如加了对象所属的架构后,系统就没办法进行参数化了,但很有意思的是query_hash和query_plan_hash都相同,也就是说明本质上这些查询都是一样的。

所以可以通过group by这些hash值,计算编译了多少次。


不想长大啊

发布了416 篇原创文章 · 获赞 135 · 访问量 94万+

他的留言板
关注

原文地址:https://www.cnblogs.com/lonelyxmas/p/12019954.html

时间: 2024-08-12 00:48:19

SQL Server中语句的自动参数化的相关文章

使用sql语句创建修改SQL Server标识列(即自动增长列)

一.标识列的定义以及特点SQL Server中的标识列又称标识符列,习惯上又叫自增列.该种列具有以下三种特点:1.列的数据类型为不带小数的数值类型2.在进行插入(Insert)操作时,该列的值是由系统按一定规律生成,不允许空值3.列值不重复,具有标识表中每一行的作用,每个表只能有一个标识列.由于以上特点,使得标识列在数据库的设计中得到广泛的使用.二.标识列的组成创建一个标识列,通常要指定三个内容:1.类型(type)在SQL Server 2000中,标识列类型必须是数值类型,如下:decima

SQL Server中常用的SQL语句

1.概述 2.查询概述 3.单表查询 4.连接查询 5.带有exists的相关子查询 6.SQL的集合操作 7.插入操作 8.删除操作 9.修改操作 10.数据定义 11.视图 1.概述 名词 笛卡尔积.主键.外键 数据完整性 实体完整性:主属性不能为空值,例如选课表中学号和课程号不能为空 参照完整性:表中的外键取值为空或参照表中的主键 用户定义完整性:取值范围或非空限制,例如:性别(男女),年龄(0-130) 表连接 自然连接:与等值连接(a.id=b.id)相比,连接后的表只有一列id,而不

SQL Server中的SQL语句优化与效率

很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解.比如: select * from table1 where name='zhangsan' and tID > 10000 和执行: select * from table1 where tID > 10000 and name='zhangsan' 一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看,这两个语句的确是不一样,如果tID是一个聚合索引,那

Sql Server中如何快速修正SQL 语句错误

本文将和大家讨论一些关于找SQL 错误的问题. 现在的系统基本都是需要用到数据库的,既然用到数据库我们就要写SQL 脚本,常用的做法是现在Microsoft Sql Server Management Sudio写好调试好,然后贴到 代码中,但这样就能保证我们的SQL 脚本正常运行吗?那如果带参数的SQL 或存储过程出现问题呢?如果数据出现问题,我们应该怎么找出错误的SQL 呢? 带着这个疑问,开始我们今天的讨论.以前用代码和数据库打交道,出现数据问题,我们会打个断点一步一步的调试,就像这样:

SQL Server中一些有用的日期sql语句

1.一个月第一天的 SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2.本周的星期一 SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0) 3.一年的第一天 SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) 4.季度的第一天 SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0) 5.当天的半夜 SELECT DATEAD

SQL Server中常用的SQL语句(转):

SQL Server中常用的SQL语句 转自:http://www.cnblogs.com/rainman/archive/2013/05/04/3060428.html 1.概述 名词 笛卡尔积.主键.外键 数据完整性 实体完整性:主属性不能为空值,例如选课表中学号和课程号不能为空 参照完整性:表中的外键取值为空或参照表中的主键 用户定义完整性:取值范围或非空限制,例如:性别(男女),年龄(0-130) 表连接 自然连接:与等值连接(a.id=b.id)相比,连接后的表只有一列id,而不是两列

为什么SQL语句Where 1=1 and在SQL Server中不影响性能

    最近一个朋友和我探讨关于Where 1=1 and这种形式的语句会不会影响性能.最后结论是不影响.     虽然结论正确,但对问题的认识却远远没有解决问题的根本.实际上在T-SQL语句的书写过程中经常犯得错误就是得出一个很窄的结论,然后教条式的奉若圣经,对于T-SQL领域来说,在网上经常可以看到所谓的优化守则,随便在网上搜了一些摘录如下: 不要有超过5个以上的表连接(JOIN) 考虑使用临时表或表变量存放中间结果 少用子查询 视图嵌套不要过深,一般视图嵌套不要超过2个为宜. 对出现在wh

SQL SERVER SELECT语句中加锁选项的详细说明 [转]

SQL Server提供了强大而完备的锁机制来帮助实现数据库系统的并发性和高性能.用户既能使用SQL Server的缺省设置也可以在select 语句中使用“加锁选项”来实现预期的效果. 本文介绍了SELECT语句中的各项“加锁选项”以及相应的功能说明. 功能说明: NOLOCK(不加锁) 此选项被选中时,SQL Server 在读取或修改数据时不加任何锁. 在这种情况下,用户有可能读取到未完成事务(Uncommited Transaction)或回滚(Roll Back)中的数据, 即所谓的“

SQL Server中存储过程 比 直接运行SQL语句慢的原因

问题是存储过程的Parameter sniffing 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1. 存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度. 2. 经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete时),可将此复杂操作用