Sql Server之旅——第十二站 sqltext的参数化处理

  说到sql的参数化处理,我也是醉了,因为sql引擎真的是一个无比强大的系统,我们平时做系统的时候都会加上缓存,我想如果没有缓存,就不会有什么

大网站能跑的起来,而且大公司一般会在一个东西上做的比较用心,比较细,sqlserver同样也使用了缓存,其中就包括Data cache 和Plan cache两个大头。

现在我们也知道了Plan cache包括上一篇生成的xml结构和sql text,更有趣的是,sql text 还可以做到参数化。。。也就是模板化了。。

一:Sql参数化

<1> 先来做一个Person表,插入1000条数据,然后清空下缓存,再select出一个数据,如图:

1 DROP TABLE dbo.Person
2 CREATE TABLE Person(ID INT IDENTITY,NAME CHAR(5) DEFAULT ‘aaaaa‘)
3 INSERT INTO dbo.Person DEFAULT VALUES
4 go 1000
5
6 DBCC freeproccache
7 SELECT * FROM dbo.Person WHERE ID=100

<2> 数据已经查询出来了,下面我们看下dm_exec_sql_text中的sql会是怎样?

1 SELECT usecounts,objtype,cacheobjtype, plan_handle,query_plan,text FROM sys.dm_exec_cached_plans
2 CROSS APPLY sys.dm_exec_query_plan(plan_handle)
3 CROSS APPLY sys.dm_exec_sql_text(plan_handle)
4 WHERE text LIKE ‘%Person%‘

从上面的图中可以看到,当我select一下后,出现了两个sql text,第一个叫Adhoc(即时查询),一个叫Prepared(参数化),然后我点击第二个记录

的query_plan,会出现图形化的执行计划,如下图:

跟着好奇心,我继续点击第三个记录的query_plan会是怎样???

通过这两个sql text的执行计划,不知道你观察出来下面四点了没有:

(1) 我的sql是执行表扫描的,这个没有问题,问题在于我的两个sql text中,第一个plan居然没有完整的执行计划,而仅仅是一个图形化的select,

第二个参数化sql,它的plan是一个完整的执行计划。。。那这说明什么呢???既然Prepared是完整的执行计划,那干嘛还要把adhoc这个

sql缓存起来呢???其实这个我也不清楚。。。我猜测肯定是让引擎快速的找到prepared这个完整的执行计划吧。。。

(2)  就是想为什么sqltext要做参数化,仔细想想应该明白参数化的目的就是为了重用执行计划,因为这时候的xml已经生成好了,不然的话,你

每次执行的sql中只要参数不同都要生成一次query_plan的xml,是不是会拉查询速度的后腿呢???

(3)   你有没有关注到参数化的类型是tinyint,看到这个tinyint我马上就想破它了,我们知道tinyint就是byte类型,表示的范围也就到256...也许

    引擎看我where 100才觉得我好欺负。。。那我现在想法就是where 500,看看会是什么效果???

1 SELECT * FROM dbo.Person WHERE ID=500
2
3 SELECT usecounts,objtype,cacheobjtype, plan_handle,query_plan,text FROM sys.dm_exec_cached_plans
4 CROSS APPLY sys.dm_exec_query_plan(plan_handle)
5 CROSS APPLY sys.dm_exec_sql_text(plan_handle)
6 WHERE text LIKE ‘%Person%‘

从图中可以看到,当我where 500的时候,引擎会再次生成一个prepared的sqltext,这样就有两个prepared了,那我在想,为什么不直接

   给一个(@1 int)呢???像目前这样sql引擎的处理方式,会有几条prepared记录的xml和sqltext的,是不是有点浪费内存呢?

(4)  仔细想想你会知道,sql引擎还是挺色胆包天的,因为prepared的记录已生成,执行计划也就生成了。。。。那说明什么呢???说明这时候

  的xml已经是死的了,也就说明执行计划也是定死的了,难道@1参数的不同不会导致执行计划有变更么???如果有变更难道还让我执行原来

这个表扫描执行计划么???有点奇葩,好了,我准备在下面仔细说说。

二:参数的变化对prepared的影响

  如果你看过之前的博文,你应该明白有一个叫做书签查找的玩意。。。它的原理是在非聚集索引上通过B树查找,当查找到目标键的时候拿到这

个键的聚集索引key,然后通过key来取数据的记录,如果你的非聚集索引的键值的唯一性比较高,这时候sql引擎会走书签查找,但是如果你的键值

唯一性比较低或者在数据量比较小的情况,sql引擎就不会走书签查找,而转向聚集索引扫描。。。那这说明什么呢?说明执行计划在有些时候会跟

(@1 int)这个值有关系。。。那这样的话貌似就不能重用执行计划了,对吧。。。。为了验证sql引擎怎么处理的,我们来做一个测试。

1.先清空缓存,再在Name列上建索引,然后我们select下,如下图:

1 DBCC freeproccache
2 CREATE INDEX idx_Name ON dbo.Person(NAME)
3 SELECT * FROM dbo.Person WHERE NAME=‘aaaaa‘

2. 然后还是继续看看xml和sqltext

你有什么发现吗?在记录中并没有发现什么prepared记录,这说明什么。。。说明sqlserver很聪明,它知道Name可能会有 “表扫描”到

“书签扫描”的来回切换,为了验证问题,我继续向Person表插入1w条数据,然后再插入一个唯一性数据。如下图:

1 INSERT INTO dbo.Person DEFAULT VALUES
2 go 10000
3 INSERT INTO dbo.Person(NAME ) VALUES (‘ccccc‘)

确实,如我猜想的一样,sqlserver很聪明的。。。如果它觉得这个Name不靠谱的话,它是绝对不敢给这条sqltext生成prepared的。。。转过

头来再想想第一条为什么会有sqltext,那是因为a列不管取值多少,都改变不了走表扫描的现实,所以sql引擎才敢这么大胆。。。突然觉得人生

不就是这样嘛????很多人都是不把稳的事情是绝对不敢做的。。。

时间: 2024-10-21 23:42:24

Sql Server之旅——第十二站 sqltext的参数化处理的相关文章

Sql Server之旅——第十四站 深入的探讨锁机制

原文:Sql Server之旅--第十四站 深入的探讨锁机制 上一篇我只是做了一个堆表让大家初步的认识到锁的痉挛状态,但是在现实世界上并没有这么简单的事情,起码我的表不会没有索引对吧,,,还 有就是我的表一定会有很多的连接过来,10:1的读写,很多码农可能都会遇到类似神乎其神的死锁,卡住,读不出来,插不进入等等神仙的事情导致性 能低下,这篇我们一起来探讨下. 一: 当select遇到性能低下的update会怎么样? 1. 还是使用原始的person表,插入6条数据,由于是4000字节,所以两条数

Sql Server之旅——第十站 看看DML操作对索引的影响

我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 现在我们已经知道,索引都是以B树的形式存在的,既然是B树,我们就要看看他们的叶子节点和分支结点,先准备点测试数据,如下图: CREATE TABLE Person(ID INT,NAME CHAR(200)) CREATE INDEX idx_Name ON Person(NAME) DECLAR

Sql Server之旅——第十一站 简单说说sqlserver的执行计划

原文:Sql Server之旅--第十一站 简单说说sqlserver的执行计划 我们知道sql在底层的执行给我们上层人员开了一个窗口,那就是执行计划,有了执行计划之后,我们就清楚了那些烂sql是怎么执行的,这样 就可以方便的找到sql的缺陷和优化点. 一:执行计划生成过程 说到执行计划,首先要知道的是执行计划大概生成的过程,这样就可以做到就心中有数了,下面我画下简图: 1. 分析过程 这三个比较容易理解,首先我们要保证sql的语法不能错误,select和join的表是必须存在的,以及你是有执行

SQL Server 2008空间数据应用系列二:空间索引(Spatial Index)基础

原文:SQL Server 2008空间数据应用系列二:空间索引(Spatial Index)基础 在前一篇博文中我们学习到了一些关于地理信息的基础知识,也学习了空间参照系统,既地球椭球体.基准.本初子午线.计量单位.投影等相关理论知识,我们可以使用这些空间参照系统组件来定义一系列应用于地球空间上的几何图像来表示地理空间中的特定功能,表示着地球上一个一个特定的位置点. 本篇主要介绍地理空间索引的概念以及微软SQL Server 2008 R2中的空间索引的应用. 一.空间索引 空间索引是指依据空

浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色

浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色 本篇文章是系列文章中的第二篇,以防你还没有看过第一篇.上一篇的文章地址如下: 浅谈SQL Server中的事务日志(一)----事务日志的物理和逻辑构架 简介 每一个SQL Server的数据库都会按照其修改数据(insert,update,delete)的顺序将对应的日志记录到日志文件.SQL Server使用了Write-Ahead logging技术来保证了事务日志的原子性和持久性.而这项技术不仅仅保证了ACID

(转)SQLServer_十步优化SQL Server中的数据访问 二

原文地址:http://tech.it168.com/a2009/1125/814/000000814758_all.shtml 第五步:识别低效TSQL,采用最佳实践重构和应用TSQL 由于每个程序员的能力和习惯都不一样,他们编写的TSQL可能风格各异,部分代码可能不是最佳实现,对于水平一般的程序员可能首先想到的是编写TSQL实现需求,至于性能问题日后再说,因此在开发和测试时可能发现不了问题. 也有一些人知道最佳实践,但在编写代码时由于种种原因没有采用最佳实践,等到用户发飙的那天才乖乖地重新埋

(转)SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)

二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编号:分页编号:Slot编号 用于锁定堆中的单个行的行标识符. 索引键 KEY KEY 7 6字节哈希值 索引中用于保护可序列化事务中的键范围的行锁. 分页 PAGE PAG 6 文件编号:分页编号 数据库中的 8 KB 页,例如数据页或索引页. 范围 EXTENT EXT 8 文件编号:范围的第一个

SQL SERVER的锁机制(二)——概述(锁的兼容性与可以锁定的资源)

二.完整的锁兼容性矩阵(见下图) 对上图的是代码说明:见下图. 三.下表列出了数据库引擎可以锁定的资源. 名称 资源 缩写 编码 呈现锁定时,描述该资源的方式 说明 数据行 RID RID 9 文件编号:分页编号:Slot编号 用于锁定堆中的单个行的行标识符. 索引键 KEY KEY 7 6字节哈希值 索引中用于保护可序列化事务中的键范围的行锁. 分页 PAGE PAG 6 文件编号:分页编号 数据库中的 8 KB 页,例如数据页或索引页. 范围 EXTENT EXT 8 文件编号:范围的第一个

SQL Server 性能优化实战系列(二)

SQL Server datetime数据类型设计.优化误区 一.场景 在SQL Server 2005中,有一个表TestDatetime,其中Dates这个字段的数据类型是datetime,如果你看到表的记录如下图所示,你最先想到的是什么呢? (图1:数据列表) 你看到这些数据,是不是觉得这样的设计既浪费了存储空间,又使得这个列的索引增大,查询起来更慢,你也想使用一些其它的数据类型来代替这个datetime吧? 其实大家都是这么想的,这个方向是100%正确的,但是在写这篇文章以前,我进入了两