利用DBCC PAGE查看SQL Server中的表和索引数据

2016-02-19 19:34 5 1 收藏

岁数大了,QQ也不闪了,微信也不响了,电话也不来了,但是图老师依旧坚持为大家推荐最精彩的内容,下面为大家精心准备的利用DBCC PAGE查看SQL Server中的表和索引数据,希望大家看完后能赶快学习起来。

【 tulaoshi.com - 编程语言 】

  问题

  我读了很多关于数据库页和如何利用它们来存储表数据和索引数据的文章。有没有一种方法可以让我真正看到这方面的信息呢?

  专家解答

  在SQL Server中最糟的一个秘密是没有正式文件说明的DBCC PAGE命令,而这个命令可以让你查看数据和索引页的内容。其中,某些信息仍然是神秘的,而你喜爱的搜索引擎是一个让你开始着手查找输出结果背后展示的很多意思的好去处。尽管如此,我发现,当我遍历数据库来解决数据库问题而我只有通过页信息来继续摸索这个问题时,或者当我只是想看看当遇到某些数据库操作发生时数据库引擎如何处理数据和索引页时,我发现DBCC命令是很有用的。

DBCC PAGE 参数DBCC PAGE
(
['database name'|database id], -- can be the actual name or id of the database
file number, -- the file number where the page is found
page number, -- the page number within the file
print option = [0|1|2|3] -- display option; each option provides differing levels of information
)

  首先,让我们来创建一个示例数据库和表,这将有利于我们描述通过DBCC PAGE你看到了什么。

  USEMASTER
  GO
  CREATEDATABASEMSSQLTIPS
  GO
  USEMSSQLTIPS
  GO
  CREATETABLEDBO.EMPLOYEE
  (
  EMPLOYEEIDINTIDENTITY(1,1),
  FIRSTNAMEVARCHAR(50)NOTNULL,
  LASTNAMEVARCHAR(50)NOTNULL,
  DATE_HIREDDATETIMENOTNULL,
  IS_ACTIVEBITNOTNULLDEFAULT1,
  CONSTRAINTPK_EMPLOYEEPRIMARYKEY(EMPLOYEEID),
  CONSTRAINTUQ_EMPLOYEE_LASTNAMEUNIQUE(LASTNAME,FIRSTNAME)
  )
  GO
  INSERTINTODBO.EMPLOYEE(FIRSTNAME,LASTNAME,DATE_HIRED)
  SELECT'George','Washington','1999-03-15'
  GO
  INSERTINTODBO.EMPLOYEE(FIRSTNAME,LASTNAME,DATE_HIRED)
  SELECT'Benjamin','Franklin','2001-07-05'
  GO
  INSERTINTODBO.EMPLOYEE(FIRSTNAME,LASTNAME,DATE_HIRED)
  SELECT'Thomas','Jefferson','2002-11-10'
  GO

  现在,我们可以去看看SQL Server如何存储数据和索引页。但是我们该从哪里开始?我们能从哪里找到这张表的页和它的数据的所在?其实,这里还有另外的DBCC命令 – DBCC IND – 你可以用它来列出一张表的所有数据和索引页。

DBCC IND参数DBCC IND
(
['database name'|database id], -- the database to use
table name, -- the table name to list results
index id, -- an index_id from sys.indexes; -1 shows all indexes and IAMs, -2 just show IAMs
)

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  让我们通过运行下面的命令行来列出EMPLOYEE表的页结构。

  ListdataandindexpagesallocatedtotheEMPLOYEEtable
  DBCCIND('MSSQLTIPS',EMPLOYEE,-1)
  GO

  以下是我的数据库所输出的结果:

(本文来源于图老师网站,更多请访问https://www.tulaoshi.com/bianchengyuyan/)

  请注意,为了更简洁,上述的图像只列出了执行DBCC命令后输出的前面11列的结果。还有另外的列没有列出来,这些列包括可以让你看到这些页如何彼此关联的链接列表信息。

  这一次的数据意味着什么呢?为了达到这篇文章讲述的方法的目的,我们专注于一些关键列。列PageFID和PagePID分别代表页所在的文件数目和数据在文件内的页数目。IndexID是在sys.indexes之中找到的索引的index_id。PageType表示页的类型,Type = 1是数据页,Type = 2是索引页,Type = 10是保存页本身的IAM页。IndexLevel是按页数时IAM结构的级别。如果 level = 0,那么这是索引的叶级别页。要想了解更多这些列的详细信息(毕竟这是一个没有在正式文件中说明的命令),可以看看由微软前存储引擎专家Paul Randal写的MSDN blog,这个博客很详细地解释了这些。

  有了这些信息,现在我们可以看看我们插入的Washington, Franklin和Jefferson三行是如何存储到EMPLOYEE表中的。EMPLOYEE表有一个聚簇索引(主键定义的结果),它表示应该有一个由DBCC IND输出结果产生的IndexID = 1(index_id = 1指向聚簇索引,在这个聚簇索引中,对于表来说叶级别页是真正的数据)。观察由DBCC IND产生的输出结果,我们可以看到,这个PageType = 1聚簇索引可以在文件数(PageFID) = 1和页码(PagePID) = 143的地方找到。这里有四个不同的显示页数据的打印选项。我使用的是包含页标题信息和数据的打印选项3。

  注意:在我们能够运行DBCC PAGE之前,要求跟踪标志3604设置成指导引擎去发送输出结果到控制台,否则你将什么都看不到。

  DBCCTRACEON(3604)
  DBCCPAGE('MSSQLTIPS',1,143,3)WITHTABLERESULTS
  GO

  滚动到这些结果的结尾处,我们可以看到,我们的数据已经存储了并且它存储在聚簇索引的列上。数据行存储在以零点偏移开始的槽变量上。

  EMPLOYEE表也有一个非聚簇索引(通过在表中定义的约束)。让我们查看创建的非聚簇索引。再次观察DBCC IND输出,我们可以很容易确定非聚簇页,因为它是IndexID = 2 (PageType = 2)并且它可以在文件数(PageFID)= 1和页码(PagePID) = 153中找到。注意,如果我们有表上的不同索引,我们可以查看sys.indexes并且得到随后要用来查看具体索引的index_id。现在,让我们来看看索引数据:

  DBCCPAGE('MSSQLTIPS',1,153,3)WITHTABLERESULTS
  GO

  滚动到这些结果的末端,我们可以看到我们的索引数据是按姓和名的逻辑排列来存储的。你也应该注意到,聚簇索引键也存储在索引行中。当需要一个书签查找(bookmark lookup)时,引擎可以用它来检索聚簇索引(这种类型的查找发生在索引栏没有包含需要用来满足一个查询的所有栏时)。

  如果这里没有表上的聚簇索引,那么另外的栏将会指向实际的数据页。让我们重新创建作为非聚簇索引的主键并且重新检查由UNIQUE约束创建的非聚簇索引。注意,通过重新创建没有聚簇索引的表,基本页的数据已经改变了。通过DBCC IND,你可以看到这些页结构如何改变。

  ALTERTABLEDBO.EMPLOYEEDROPCONSTRAINTPK_EMPLOYEE
  GO
  ALTERTABLEDBO.EMPLOYEEADDCONSTRAINTPK_EMPLOYEE
  PRIMARYKEYNONCLUSTERED(EMPLOYEEID)
  GO
  DBCCIND('MSSQLTIPS',EMPLOYEE,-1)
  DBCCPAGE('MSSQLTIPS',1,155,3)WITHTABLERESULTS
  GO

  正如你所看到的,在HEAP表中的索引(这张表不是聚簇的)存储了一个不同的指示器,这个指示器直接指向包含要求的另外的数据的页面。


  这些都是很简单的例子,但是它们对给你关于如何和在哪里获得和显示数表和索引数据的想法是绰绰有余的。在以后的方法中,我将利用更多的例子来说明问题,这些例子将显示当一行改变并且它不适合某一页时将会发生什么,当行被删除时将发生什么,还有DBCC PAGE如何帮助解决阻塞和死锁问题。

  我必须强调,DBCC IND和DBCC PAGE没有在正式文件中说明,它们可能在以后的SQL Server版本中会消失。在那出现之前,我会继续利用这些命令作为窥探引擎的数据存储技术和解决SQL Server问题的主要工具。

来源:https://www.tulaoshi.com/n/20160219/1621333.html

延伸阅读
标签: SQLServer
SQL SERVER 2005中,终于引入了表分区,就是说,当一个表里的数据很多时,可以将其分拆到 多个的表里,大大提高了性能。下面举例子说明之 比如,在C盘下建立如下几个目录 C:Data2Primary C:Data2FG1 C:Data2FG2 C:Data2FG3 C:Data2FG4 其中primary存放的是主数据库文件,其他FG1--FG4存放四个单独的文件组,可以见创立数据库 Data Partition DB...
今天在我和一家软件公司的开发人员讨论数据库设计调优的时候又讨论到了表变量和临时表的问题,觉得这个问题确实是一个争议比较大的问题。 其实从上次发表了表变量和临时表的一个帖子http://database.ctocio.com.cn/tips/442/8206442.shtml以来,也有些人留言,也有些人发过邮件讨论这个问题。其实表变量和临时表的区别虽然有一些,但...
标签: SQLServer
     今天客户反映数据库文件空间增长过快 ,需要分析数据库表存放空间分配情况,临时写了以下过程, 与大家共享。 /******************************** 功能:获取表的空间分布情况  ycsoft 2005-07-13 **********************************/ if not exists (select * from dbo.sysobjects where id = object_id(N'[db...
索引在数据库相关工作者的日常工作中占据了很重要的位置,索引需要牵涉到索引创建、优化和维护多方面的工作,本文以实例结合相关原理来介绍索引维护相关的知识。文中的相关代码,也可以满足多数情况下索引的维护需求。 实现步骤 1. 以什么标准判断索引是否需要维护? 2. 索引维护的方法有哪些? 3. 能否方便地整理出...
标签: SQLServer
一、了解DBCC DBCC(database consistenecy checker,简称dbcc) 是一个实用命令集,用来检查数据库的逻辑一致性及物理一致性。 数据库控制台命令语句可分为以下类别: 维护: 对数据库、索引或文件组进行维护的任务。 杂项: 杂项任务,如启用跟踪标志或从内存中删除 DLL。 信息: 收集并显示各种类型信息的任务。 验证: 对数...

经验教程

513

收藏

48
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部