SQL Server使用游标处理Tempdb究极竞争-DBA问题-程序员必知

SQL Server tempdb分配竞争算是DBA老生常谈的问题了,几乎现在所有的DBA都知道多建几个文件来解决/缓解问题.但是深层次的的竞争依旧不可避免.这里给大家剖析下游标在tempdb中的特点使其在一定场景下替代临时表/表变量对象,解决深层次的tempdb竞争问题.

在抛出这个不可避免的问题之前我们先简要看下什么是tempdb竞争.

我们拿SQL Server创建一个临时表的过程来描述

1 在系统表中创建表的条目(系统数据页中)

2 分配一个IAM页并找到一个混合区在PFS页中标记

3 分配一个数据页(查看SGAM页,查看PFS页后并更新,更新IAM页)

4 表记录记录到系统表中

从上述过程可以看出创建一个简单临时表需要查找,更新一系列的系统表/系统数据页,且当使用完删除临时表时上述操作逆向进行.索引相应的创建/销毁一旦大量并发,内部竞争也就产生了.虽然tempdb的缓存策略一定程度可以缓解相应创建过程的IAM,数据页分配, Sql Server tempdb原理-缓存机制解析实践,但竞争依旧.

可以看到SGAM,PFS等系统页是表创建过程的必经之路,他的分配竞争也就十分明显了.这也就是为什么采用多个数据文件,让系统页(包含系统表)在分散在多个数据文件中的以减轻分配竞争的压力原因.

到此也许大家都改猜到了终极问题是什么了,就是对系统对象的操作.连SQL Server大牛Paul Randal都为之头疼的问题.

具体哪些对象呢,我们可以简单测试捕捉下如图1-1

使用SQLQUERYSTRESS捕捉

Code

create table #t (id int, str1 varchar(10) ) ---SSMS中开启会话捕捉 SELECT resource_description,* FROM SYS.dm_os_waiting_tasks WHERE session_id>50

图1-1

可以看到图中tempdb中系统页 2:1:53中发生典型的Pagelatch竞争.我们用dbcc page来看下页的情况如图2-2

Code

dbcc traceon(3604) go dbcc page(2,1,53,1) select OBJECT_NAME(7)----the object_id from dbcc page

图2-2

可以看到在系统对象sysallocunits处发生了竞争,当然还有许多其他的系统对象,感兴趣的朋友自行捕捉.

大量的针对系统对象表的操作使得tempdb其吞吐难以得到进一步的提升,这个是由系统本身的运作方式引发的,当然面对如此巨量的tempdb使用,就没有别的方式了吗?这时我不能给肯定的答案,但可以给大家一个IT界的流行答案:It depends :)

在介绍游标前,先简单说下面对tempdb竞争中针对系统表竞争的常规处理方式

1 减小针对系统对象的事务大小(如select * into #的使用)

2 减小tempdb的使用频次(看似废话,但实际中的确可能用不到这么多)

3 临时对象中少使用约束造成额外的系统对象负担.

好了接下来该说游标了,貌似八竿子打不着的事儿,实际上的确如此,我们只是利用游标的特性在极其特殊的场景下来解决相应问题.

也许你已经猜到了,游标是使用tempdb的,归类到worktables中,使用worktables的对象如游标,dbcc checkdb,merge join,exchange spill等等.worktables是tempdb中一种普遍而又特殊的使用方式,他只在SQL Server内部中应用,给它定义为”temporary rowsets”,他的object id是负的,且无需系统表的记录!

我们来简单验证说明下

code

use tempdb checkpoint ---生产环境中慎用 dbcc checkdb(master) –这里采用dbcc checkdb探究worktables select Description,* from fn_dblog(null,null)

得到的tempdb Log如图 2-1

图2-1

我们用dbcc page分析此页 可以看到这个是个IAM页如图2-2

code

dbcc traceon(3604) dbcc page(2,4,104,3)

图2-2

我们进而分析IAM分配的数据页,发现他就是一个简单的数据页,不属于任何系统对象如图2-3

Code

dbcc traceon(3604) dbcc page(2,5,104,3)

图2-3

OK,至此联想起游标同样适用worktables,我们可能联想到了一些游标适用的场景居然还可以帮助tempdb缓解竞争.至于何种场景?It depends,大家自己去联想吧,但tempdb遇到相应竞争时我是否可以采用?朋友们自己抉择吧.

最后看图说话如图2-4

Code

--cursor declare @cur cursor set @cur =cursor For select * from tt --temp table create table #tt (id int) insert into #tt select * from tt

图2-4

以上叙述是否改变了你对游标的看法呢?程序员朋友们,当DBA告诉你使用tempdb太多时是否考虑换种方式使用tempdb, DBA朋友们,不要轻易告诉程序员们过度使用tempdb.

结语 任何系统的愉快运转都是基于某种状态的平衡.我们需要在复杂环境中的性能瓶颈,资源消耗,相应时间等等因素中找到平衡点.什么样的平衡点? It depends :)

ps:sql server 数据库 ' ' 附近有语法错误

昨天做项目时候,遇到标题的问题,代码跟踪把sql 语句 复制出来在数据库执行不了,然后重新写个一模一样的,然后在 赋值到代码中,还是同样的错误,就是不知道哪里出现了错误,最后 把 sql 语句写成最简单的 select * from tab  还是同样的错误。

然后 ,然后就不会了。

最后在这个语句写同样的语句,最后发现问题了,新写的sql 语句的 select 变 颜色了,而之前的赋值出来的  select 和 字段 表名的颜色一样,证明系统 不承认它是关键字,把这个select 删掉在 这个位置上重新写,还是同样的错误,最后发现原来在 这个select 前面有个全角的 空格,全角空格真的是用肉眼看不出来啊,恍然大悟,才知道  '   '    附近有语法错误 ,意思是  空格  有语法错误,证明不是 sql server 支持的 空格格式。

这个问题百度了,也没解决,希望 可以帮到其他人,又不是特别难的东西,但是找到问题还是很浪费时间。

时间: 2024-10-25 04:04:43

SQL Server使用游标处理Tempdb究极竞争-DBA问题-程序员必知的相关文章

SQL Server使用游标处理Tempdb究极竞争-DBA问题-程序员必知_MsSql

SQL Server tempdb分配竞争算是DBA老生常谈的问题了,几乎现在所有的DBA都知道多建几个文件来解决/缓解问题.但是深层次的的竞争依旧不可避免.这里给大家剖析下游标在tempdb中的特点使其在一定场景下替代临时表/表变量对象,解决深层次的tempdb竞争问题. 在抛出这个不可避免的问题之前我们先简要看下什么是tempdb竞争. 我们拿SQL Server创建一个临时表的过程来描述 1 在系统表中创建表的条目(系统数据页中) 2 分配一个IAM页并找到一个混合区在PFS页中标记 3

使用 Microsoft SQL Server 2000 的全文搜索功能构建 Web 搜索应用程序

server|web|程序|全文搜索 使用 Microsoft SQL Server 2000 的全文搜索功能构建 Web 搜索应用程序 Andrew B. CenciniMicrosoft Corporation 2002年12月 适用于:    Microsoft SQL Server 2000摘要:学习如何充分利用 SQL Server 2000 的全文搜索功能.本文包含有关实现最大吞吐率和最佳性能的几点提示和技巧. 目录简介 全文搜索功能简介 配置全文搜索功能 全文查询 排位和优化 其他

SQL Server 利用锁提示优化Row_number()-程序员需知

原文:SQL Server 利用锁提示优化Row_number()-程序员需知 网站中一些老页面仍采用Row_number类似的开窗函数进行分页处理,此时如果遭遇挖坟帖的情形可能就需要漫长的等待且消耗巨大.这里给大家介绍根据Row_number()特性采用特定锁Hint提升查询速度.   直接上菜   脚本环境可在SQL Server优化技巧之SQL Server中的"MapReduce"找到   如下查询在分页中比较常见 set statistics time on select *

SQL Server 隐式转换引发的躺枪死锁-程序员需知

原文:SQL Server 隐式转换引发的躺枪死锁-程序员需知 在SQL Server的应用开发过程(尤其是二次开发)中可能由于开发人员对表的结构不够了解,造成开发过程中使用了不合理的方式造成数据库引擎未按预定执行,以致影响业务.这是非常值得注意的.这次为大家介绍由于隐式数据类型转换而造成的死锁及相应解决方案. 现实中有些程序员/数据库开发者会根据数据库的处理机制实现一些应用,如抢座应用,可能会对事务中的查询加一些列的Hint以细化粒度,实现应用的同时使得影响最低,但也有可能因为一些小细节的欠缺

Sql Server之旅——第九站 看公司这些DBA们设计的这些复合索引

原文:Sql Server之旅--第九站 看公司这些DBA们设计的这些复合索引 这一篇再说下索引的最后一个主题,索引覆盖,当然学习比较好的捷径是看看那些大师们设计的索引,看从中能提取些什么营养的东西,下面我们看 看数据库中一个核心的Orders表. 一:查看表的架构 <1> 先查看这个表的大概架构信息 1 --查看表的架构信息 2 SELECT c.column_id,c.name,t.name FROM sys.columns AS c 3 JOIN sys.types t 4 ON c.s

SQL Server之游标的基础知识

什么是游标: 游标是可以在结果集中上下游动的指针. 游标的作用: --允许定位到结果集中的特定行. --从结果集的当前位置检索一行或多行数据. --支持对结果集中当前位置的行进行修改. 注意:游标虽然很好用,但是如果滥用游标的话,会对程序的性能造成很大影响,使用的时候一定要谨慎啊! 游标的种类: MS SQL SERVER 支持三种类型的游标:Transact_SQL 游标,API 服务器游标和客户游标. (1) Transact_SQL 游标 Transact_SQL 游标是由declare

更改SQL Server 2005数据库中tempdb位置的方法_mssql2005

了解SQL Server 2005数据库的朋友可能都知道,tempdb系统数据库是一个全局资源,可供连接到SQL Server 2005实例的所有用户使用.我们有时候为了操作方便,常常会更改一下tempdb数据库的位置,那么该如何操作呢?本文我们就来介绍这一更改的过程. 获得tempdb的原始位置: select [name],[physical_name] from sys.master_files where database_id=db_id(N'tempdb') 更改tempdb数据库位

程序员必看:关于SQL Server的若干注意事项

server|程序|程序员 如果你正在负责一个基于SQL Server的项目,或者你刚刚接触SQL Server,你都有可能要面临一些数据库性能的问题,这篇文章会为你提供一些有用的指导(其中大多数也可以用于其它的DBMS). 在这里,我不打算介绍使用SQL Server的窍门,也不能提供一个包治百病的方案,我所做的是总结一些经验----关于如何形成一个好的设计.这些经验来自我过去几年中经受的教训,一直来,我看到许多同样的设计错误被一次又一次的重复. 你了解你用的工具吗? 不要轻视这一点,这是我在

C# 连接 SQL Server 数据库,出现异常:provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接

System.Data.SqlClient.SqlException: 在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接. (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接) 解决方法:   SQL Server 实例上启用远程连接1."开始->所有程序->Microsoft SQL Server 2008