SQL Server优化器特性-动态检索

前段时间我写的文章SQL Server 隐式转换引发的躺枪死锁 中有的朋友评论回复说在SQL2008R2测试时并未出现死锁,自己一测果然如此,因此给大家带来的疑惑表示抱歉,这里我就解释下其原因.

回顾:SQL2012中发生死锁的原因已经向大家解释了,因为隐式转换造成的表扫描扩大了锁规模.但在SQL2008R2中就未有同样的现象出现,很显然锁规模没有扩大,原因在于SQL Server的优化器为我们做了额外的事情-动态检索

动态检索:基于索引查找的优势,SQL Server(部分版本)会尝试将一些情形进行内部转换,使得索引检索的覆盖面更广,对其实重要补充.

还是之前那篇的实例,我们在SQL2008R2中看到的update的执行计划如图1-1

Code 生成测试数据

create table testlock
(ID varchar(10) primary key clustered,
col1 varchar(20),
col2 char(200))
go----------create test table

declare @i int
set @i = 1
while @i < 100
begin
insert into testlock
select right(replicate(‘0‘,10)+ cast(@i as varchar(10)),10),‘aaa‘,‘fixchar‘
set @i = @i+1
end
go----------generate test data

Code 死锁语句

declare @ID nvarchar(10)

begin tran 

select  top 1 @ID = ID from testlock with(updlock, rowlock, readpast)
where col1 = ‘aaa‘
order by id asc

select  @ID

waitfor delay ‘00:00:20‘

update testlock set col1 = ‘bbb‘ where id = @ID

commit tran

图1-1

可以看到因为SQL Server将变量@ID进行了额外的转换运算,使得其作为数值进行处理,从而进行索引查找以提升效率,这就是动态检索的初衷,在此却也同时规避了死锁的发生.

关于动态检索

在进行动态检索时,优化器会将常量,标量的计算的CPU,IO的预估消耗置0,以避免查询子树的大小变化造成可能的执行计划改变,同时将相应的检索数值区间及检索方式作为查询操作的输入进行检索.如图1-2

图1-2

实现细节

可以看到图1-2中的输出列表Expr-1013,Expr-1014,Expr-1012而在实际执行操作中这三个输出对象分别代表常量的开始值,结束值,和所需执行的操作,打开其XML执行计划详细信息可以看到Expr-1013值为@ID, Expr-1014值为@ID, Expr-1012值为62,而62就是代表”=”

如图1-3所示

图1-3

另一个实例

declare @ID nvarchar(10)

set @ID=0000000006

update testlock set col1 = ‘bbb‘ where id > @ID

如果是大于则相应的XML执行计划如图1-4

图1-4

注:其输出表达式代表的含义各版本中应相同,但未验证.

输出列表中检索方式其它运算符的值代表含义感兴趣的朋友可以自行测试验证.

后记:此现象已经反馈给SQL Server 相关team.

再次祝大家羊年大吉,钱途无量!

时间: 2024-08-08 09:48:24

SQL Server优化器特性-动态检索的相关文章

SQL Server优化器特性-隐式谓词

原文:SQL Server优化器特性-隐式谓词 我们都知道,一条SQL语句提交给优化器会产生相应的执行计划然后执行输出结果,但他的执行计划是如何产生的呢?这可能是关系型数据库最复杂的部分了.这里我为大家介绍一个有关SQL Server优化器的特性-隐式谓词,并简单介绍在此特性下如何根据场景控制优化器的行为. 在这里我通过一个简单的实例来给大家说明下. code CREATE TABLE T1 (A INT, B INT) CREATE TABLE T2 (A INT, B INT) set sh

SQL Server 优化器特性导致的内存授予相关BUG

原文:SQL Server 优化器特性导致的内存授予相关BUG 我们有时会遇到一些坑,要不填平,要不绕过.这里为大家介绍一个相关SQL Server优化器方面的特性导致内存授予的相关BUG,及相关解决方式,也顺便回答下邹建同学的相关疑问. 问题描述 一个简单的查询消耗了匪夷所思的内存.(邹建同学发现的) 原文链接 Code create table test_mem ( id int identity(1,1) primary key, itemid int not null, date dat

高老大 ‘SQL Server 优化器特性导致的内存授予相关BUG’ 学习笔记

今天高老大出了好文章.在这里 自己本来对这一块比较混乱,正好借这个机会学习一下. 就用高老大的脚本.需要的直接去他那里找吧,这里就省了. 加查询优化标记前后对比 可以看到GrantedMemory是504928KB,大约是213096/1024=208.101562MB(这里的那个值好像每次都有差别,但是差距不太大.不影响效果) 加上跟踪标记后 4560/1024大概只有4MB吧. 差别很大吧~ 其实这里这些值还可能通过查询计划的XML里看,里面有更详细的信息. 如 <QueryPlan Deg

SQL Server 优化器+SQL 基础

http://www.cnblogs.com/shanksgao/tag/%E4%BC%98%E5%8C%96%E5%99%A8/ http://www.cnblogs.com/double-K/category/759248.html http://www.cnblogs.com/zhijianliutang/category/636063.html http://www.cnblogs.com/lonelyxmas/p/4685085.html       stack生成          

22. SQL -- SQL Server 2005 和SQL Server 2008新特性

SQL SERVER 2005 与SQL SERVER 2008 新特性   SQLSERVER 2005 新特性 Enhanced Data Types:存储最大8K-2G Partitioned Table(分区表):数据拆分管理 背景:一个公司,有目前现存数据以及历史数据,各在一台SER 上,服务器访问方式: SQL 2000 TABLE 1:在一张table 中,对数据进行分区 Enhanced Indexing Features SER 1 SER 2 现存数据 TABLE 1 TAB

SQL Server 2014新特性——Buffer Pool扩展

Buffer Pool扩展 Buffer Pool扩展是buffer pool 和非易失的SSD硬盘做连接.以SSD硬盘的特点来提高随机读性能. 缓冲池扩展优点 SQL Server读以随机读为主,SQL Server IO分为2部分:buffer pool管理方式,和buffer pool. SQL Server 从磁盘中读入数据,并且存放在buffer pool中以供读取和修改,修改完之后脏数据还是放在buffer pool中,当内存紧张执行lazy write把脏数据写入磁盘,并且释放内存

解决SQL Server管理器无法连接远程数据库Error: 1326错误

解决SQL Server管理器无法连接远程数据库Error: 1326错误 我们在在使用SQL Server时都会遇到使用SQL Server Management Studio无法连接远程数据库实例的问题,错误描述信息摘录如下: An error has occurred while establishing a connection to the server. (provider: Named Pipes Provider, error: 40 – Could not open a con

谈谈我的微软特约稿:《SQL Server 2014 新特性:IO资源调控》

原文:谈谈我的微软特约稿:<SQL Server 2014 新特性:IO资源调控> 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 篡写经历(Experience) 特约稿正文(Content-body) 第一部分:生活中资源调控器: 第二部分:SQL Server中资源调控器: 第三部分:SQL Server资源调控器运用场景—CPU: 第四部分:SQL Server资源调控器运用场景—IO: 第五部分:总结: 第六部分:作者简介:

SQL Server锁分区特性引发死锁解析

原文:SQL Server锁分区特性引发死锁解析 锁分区技术使得SQL Server可以更好地应对并发情形,但也有可能带来负面影响,这里通过实例为大家介绍,分析由于锁分区造成的死锁情形. 前段时间园友@JentleWang在我的博客锁分区提升并发,以及锁等待实例中问及锁分区的一些特性造成死锁的问题,这类死锁并不常见,我们在这里仔细分析下.不了解锁分区技术的朋友请先看下我的锁分区那篇实例. Code(执行测试脚本时请注意执行顺序,说明) 步骤1 创建测试数据 use tempdb go creat