わかりやすいSQLServerのデータベース構造解説(第2章)

ちょっと、古い内容になりますが、SQLServerのテーブルとオブジェクトID、ページの分類、インデックスの内部構造と動作解説、クラスタ化インデックスと非クラスタ化インデックスの違いそして格納されているデータのそれぞれの構造、付加列インデックスのメリット、dbcc pageコマンドの使用方法と出力内容についてわかりやすく記載します。

テーブルとオブジェクトID

「テーブル」を最もシンプルに表現すると、「行」と「列」の集合物と言えます。基本的にテーブルを作成するとき、テーブルに対するクエリを記述するときは、「列」と「行」を思い浮かべると思います。そのため、SQL Serverには、8KBのページを駆使して、行と列の集合物としてのテーブルを表現するための実装がされています。さっそく、8KBページとテーブルのギャップを埋めるための具体的な実装方法を確認していきましょう。
8KBの各ページには、行と列を表現するために必要な情報が格納されているのですが、その情報だけではうまく機能しません。なぜなら、各ページに列と行のデータだけが存在していても、それぞれのページがどのテーブルに所属しているのかはSQLServerには理解できないからです。
テーブルとページの関連性が明確にならないと、当然ながら、テーブルに対して実行されるクエリは適切なページからデータを取得できません。そのような理由から、それらのページをテーブルに所属するひとまとまりの存在であることを示す必要があります。そのために使用されているのが「オブジェクトID」という概念です。データベース内のすべてのテーブルには、すべて固有のオブジェクトIDが割り当てられています。

また、すべてのページは、8KBの最初から96バイトの部分まで「ページヘッダー」という管理情報を格納するための領域として使用しています。それぞれのページヘッダーに、ページが所属するテーブルが割り当てられたオブジェクトIDを埋め込むことによって、一群のページがテーブルという、ひとまとまりの存在であることが意味付けられます。

図1

データベース内に無数、存在する8KBページ群

図1

テーブルに割り当てされたオブジェクトIDを各ページのページヘッダーに埋め込んで関連付ける。

図1

ページの分類

オブジェクトIDを各ページに付与することで、データベース内に無秩序に存在していた8KB群をテーブル(または、ほかのオブジェクト)として、グループ化して関連付けることができました。しかし、ひとまとまりのグループとして扱われることになったとは言っても、その用途によって、それぞれのページは大きく異なっまた内容を保持しています。
注1:ビューなどのテーブル以外のオブジェクトにもオブジェクトIDは割り当てられます。オブジェクトIDはデータベース内でユニークです。

用途には大きく分けて2種類あります。1つはデータを格納するためです。2つ目
はインデックスを格納するためです。格納する情報の種類から、前者は「データベージ」、後者は「インデックスページ」と呼ばれています。
用途をさらに細分化すると、データページにおいては、クラスタ化インデックスを定義しているテーブルと、定義していないテーブルでは、その内容が異なります。インデックスページでも、クラスタ化インデックスと非クラスタ化インデックスではその内容が異なります。
それぞれのページがどのような用途で使用されているかの判断は、各ページのページヘッダーに格納された情報を参照することで可能です。ページヘッダー内の情報の一部として、インデックスIDが格納されています。インデックスIDが0であればデータページであることを示しています。1以上255以下の場合はインデックスページであることを示しています。

表1:ページの分類

ページインデックスページクラスタ化インデックス
非クラスタ化インデックス
データページヒープ
クラスタ化インデックスのリーフページ

インデックスページ

インデックスとは何のために存在するのか?それは、より少ないI/O回数で対象とするデータを取得することを目的として存在します。より多くのディスクサイズが必要になっても、更新時のオーバーヘッドがあっても、参照時のメリットが優先されます。
SQLServerのインデックスは、B-Tree型と呼ばれるものを選択しています。インデックスページを使用して2分岐型の木階層構造を構築し、効率的なI/Oを実現します。(図2)

図2

Binary(2分岐)Tree(木階層)構造

図2

ただし、本来必要とされるデータ以外にインデックス分のディスクが必要となります。また、データ更新時には本来のデータ以外にもインデックスページ内のデータを更新する必要が発生する場合もあり、オーバーヘッドとなってしまうことがあります。

双方の中間に位置するインデックスページは「中間ノード」と呼ばれます。ルートノードからリーフノードまで2分岐を繰り返して速やかにたどるために、必要な数のインデックスページが使用されます。テーブルの保持するデータ量に応じて、中間ノードの階層は変化します。データ量が多ければ多いほど、中間ノードの階層は深くなります。(図3)

インデックスページの階層

図3

インデックスIDが256の場合は、「BLOB(BinaryLargeObject)」と呼ばれるBKBよりも大きなサイズのデータを格納するために使用されていることを示しています。BLOBとなり得るデータ型はtextimagentext,varchar(max)nvarchar(max)です。インデックスページを使用して2分岐型の木階層構造を構築し、効率的なI/Oを実現し
ます。ただし、本来必要とされるデータ以外にインデックス分のディスクが必要となります。また、データ更新時には本来のデータ以外にもインデックスページ内のデータを更新する必要が発生する場合もあり、オーバーヘッドとなってしまうことがあります。

クラスタ化インデックスと非クラスタ化インデックスの違い

クラスタ化インデックスと非クラスタ化インデックスの違いは、主としてリーフノードにあります。非クラスタ化インデックスのリーフノードは、それ以外のノードと同様にキー値のみを保持します。しかしクラスタ化インデックスは、キー値に加えて実際のデータも保持しています。キー値はインデックスの定義された順序で並んでいさて、実データも同様に並んだ状態で格納されています。つまり、クラスタ化インデックスの実データは物理的にはキー順に並んでいるということです。(図5)

図5

クラスタ化インデックスの場合

図5

非クラスタ化インデックスの場合

図5

クラスタ化インデックスは、 常にインデックスIDを1として割り当てられ、テー ブルに対して1つのみ作成可能です。 クラスタ化インデックスに定義した並び順に テーブルの実データが並べ替えられるので、 当然のことながら1つだけしか保持で きません。一方、非クラスタ化インデックスは255個まで作成できます。一般的に、データが物理的にキー順で並ぶクラスタ化インデックスは、一定範囲 をキー順で参照するような検索で利点を発揮するとされています。(図6)一方、非 クラスタ化インデックスは、与えられたキー値を基にした、小規模データの検索に 適するとされています。

図6

1,ルートノードから範囲検索の開始点と終了点を検索

select col1,col2 from tab 1 where ClusteredIndexCol between 1 and 100
ルートノードから範囲検索の開始点と終了点を検索解説

2,リーフノードの並び順にページをスキャン

select col1,col2 from tab 1 where ClusteredIndexCol between 1 and 100
リーフノードの並び順にページをスキャン解説

図7

インデックスキーを元にルートノードからデータページを検索

select col1,col2 from tab 1 where NonClusteredIndexCol=100
インデックスキーを元にルートノードからデータページを検索解説

インデックスページの内部構造

次に、インデックスページにどのようにデータが格納されているか解説します。インデックスページには、インデックスキーとして定義された列の実際の値と管理情報が行ごとに格納されています。管理情報には、行の構造を表す情報やインデックスキーなどの所在情報が格納されています。

ヘッダー情報

インデックスページのサイズは8KBです。ページの先頭の96バイトはヘッダー情報として使用されています。ヘッダー情報には主と表2の情報が収められています。

表2

Page IDデータベース内のファイル番号とページ番号を組み合わせた情報
Next Pageページリンク中で次の順序に位置するページ番号に関する情報
Prev. Pageページリンク中で前の順序に位置するページ番号に関する情報
Object IDページが所属するオブジェクトID
Levelインデックスツリーの階層に関する情報
Index IDページが所属するインデックスID

インデックスキー行

インデックスキーを構成する列のデータなどを保持しています。主として表3の情報で構成されています。

表3

列数インデックスを構成している列の数
固定長データインデックスを構成する固定長列の実際のデータ
可変長列数インデックスを構成する可変長列の数
固定長データインデックスを構成する可変長列の実際のデータ

行オフセット配列

8KBのインデックスページの末尾2バイトは、ページ内でのインデックスキーの位置を表わすオフセットとして使用されます。

データページ

ここでのデータページの意味は、「テーブルに定義されたすべての列を、行のイメージで格納しているページ」ということになります。つまり、クラスタ化インデックスのリーフページとヒープ4を指します。データページには、テーブルに格納されるべきデータそのものが格納されています。SQLServerに対して実行されたクエリは、データページに到達することによってデータを獲得できます。

データページの内部構造

データページには、BLOBなどの一部の例外を除いて、テーブルに定義したすべての列のデータが含まれています。それに加えて、データページ自体の管理情報を保持し、各データ行にもそれぞれの管理情報が付与されています。これらの情報を基に、SQL Serverは8KBのページ群を、行と列のイメージでクエリに対する結果セットとしてクライアントへ返します。

ヘッダー情報

Levelデータページでは常に0
Index IDデータページでは常に0

データ行

データ行を構成する列のデータなどを保持しています。インデックスキー行とほぼ同じ情報を保持しているため、ここでは異なる部分のみ示します。

固定長データの長さデータ行内の固定長データの合計長

行オフセット配列

8KBのデータページの末尾2バイトは、ページ内でのデータ行の位置を表すオフセットして使用されます。

付加列インデックスのメリット

SQL Server 2005から、「付加列インデックス」という新しいオブジェクトが作成できるようになりました。

カバリングインデックス

インデックスを定義する最大の目的は、クエリから要求されたデータを取得するI/O数を出来る限り減らすことにあります。図Aでも明らかなように、IAMを使用したヒープのスキャンに比べると、非クラスタ化インデックスを使用したインデックスシーク(キー値を基にインデックスページのポインタを使用して最小I/O回数で目的データに到達する技法)が実施された場合のほうが、はるかに少ないI/O数で目的とするデータを取得できます。

図A

IAMを使用したヒープスキャン

IAMのビットがTrue(1)に設定されているエクステント内のページをスキャン

図A

インデックスシーク

キー値を元に最小I/O数で目的のデータへ到達

図A

次に、まったく同じ列構造を持つ2つのテーブルに、異なるインデックスが定義された場合について考えてみます。テーブル定義は表Aの通りで、2つのテーブル(テーブルAとテーブルBとします)とも同じです。また、格納されているデータもまったく同一とします。テーブルAとテーブルBでは、それぞれ表Bのようにインデックスを定義します。

表A:テーブル定義

会員番号int
氏名nchar(50)
住所nchar(400)

表B:インデックスの定義

テーブルAテーブルB
会員番号会員番号
氏名

このようなテーブルに対して次のクエリを実行した場合の動作の違いを確認してみます。

select [会員番号],[氏名] from [テーブルA(またはB)] where [会員番号] between 1 and 1000

テーブルAの場合は、図Bのように、「氏名」列のデータを取得するためにデータページへのアクセスが必要になります。

図B:非カバリングインデックス

図B

一方、テーブルBの場合は、インデックスに「氏名」列が含まれているため、データページへのアクセスは必要なく、インデックスのリーフページ(リーフノードに位置するページ)までで事足します(図C)。そのため、取得するデータ件数が多くなると、そのためのI/O数は各段に少なくて済みます。クエリを実行する際、すべてのI/Oがインデックスページ内で完結する、このような動作を「カバリングインデックス」と呼びます。

図C:カバリングインデックス

図C

しかし、残念ながら良い点ばかりではありません。テーブルBの各インデックスキーは、テーブル
よりも100バイト大きいため、インデックス自体のサイズが肥大化します。その影響で、必要なディスクスペースが増加します。さらに「氏名」列に対して更新を行うと、データページとすべてのインデックスページの更新が必要になります。(図D)

サイズの増加

8KBのインデックスページの1ページあたり格納件数が大きく異なるテーブルBが同じ件数を格納するためには25倍のページが必要

キーサイズ1ページあたりの格納件数
テーブルA4バイト約2000件
テーブルB104バイト約80件

「氏名」列の更新はインデックスページに影響する

update [テーブルB] set [氏名] = '...' where [会員番号] = '...'

図D:サイズの増加と更新オーバーヘッド

図D

付加列インデックス

双方の良い面を取り入れいれるために実装されたのが付加列インデックスです。付加列インデックスと従来の非クラスタ化インデックスの違いは、リーフページの構造にあります。インデックスのルートノードから中間ノードでの各インデックスページには違いがありません。通常の場合、非クラスタインデックスのリーフページにはインデックスキーのみが格納されています。一方、付加列インデックスではリーフページに、インデックスキーに加えて任意の列を保持できます。

インデックスページのリーフノードのみ「氏名」列のデータを保持

図E:付加列インデックスの構造

図E

前項の例を基に考えてみると、より利点が明確になります。次のステートメントを使用して、テーブルAに非クラスタ化インデックスではなく、付加列インデックスを作成します。(include句が列部分の定義です)

create index [付加列インデックス] on [テーブルA] ([会員番号]) include ([氏名])

これにより、テーブルAのインデックスはインデックスキーである「会員番号」に加えて「氏名」のデータをリーフページに保持することになります。そのため、次のクエリを実行しても、データページへアクセスする必要はありません。

select [会員番号],[氏名] from [テーブルA] where [会員番号] between 1 and 1000

また、リーフページ以外には「氏名」のデータを保持しないため、インデックスサイズの肥大化という前項のテーブルBの問題点がある程度軽減されます。また、「氏名」データを獲得するためにデータページアクセスする必要もありません。つまり、ディスク使用量の削減とパフォーマンスの向上が付加列インデックスのメリットということになります。

付加列参照時:データページへのアクセス不要

図F:付加列インデックスのメリット

図F

付加列更新時:インデックスページはリーフノードにのみ影響を受ける

図F

dbcc pageの使用

SQL Serverには、公式なコマンドとして各種のマニュアルには掲載されていませんが、データベース内の8KBのページをダンプ出力するコマンドが実行されています。そのコマンドとは「dbcc page」です。ここでは実際のテーブルに対してこのコマンドを実行して、格納されているデータや管理情報を確認しようと考えています。
なお、これから使用するdbcc pageおよびdbceind(インデックスが使用しているページを確認するために使用する)コマンドはデータを表示する機能のみを保持しているので、データ破損などを発生させる危険性はありません。ただし、正式にサポートされているツールではないため、仮に実際に使用した際に、表示内容が正しくない場合があったとしてもご容赦ください。

準備

ページ内の状況を確認するためのサンプルをLIST1の定義内容で作成します。以降のコマンドは、すべてクエリツール(sqlcmdやSQLServerManagementStudioなど)を使用して、SQLServerに接続して実行します。

LIST1:ページ内の状況を確認するためのサンプル

create database testdb1
go
use testdb1
go
create table tl (cl int not null, c2 char (10), c3 varchar(10), c4  varchar(10), c5 char(10))
go
insert tl values (1, 'AAA', 'AAA', 'AAA', 'AAA')
insert tl values (2, 'BBB', 'BBB', 'BBB', 'BBB')
insert tl values (3, 'CCC', 'ccc', 'ccc', 'CCC') 
go

テーブルに使用されているページの確認

dbceindコマンドを実行してテーブルが使用しているページIDを確認します。なお、コマンドシンタックスは次のとおりです。インデックスIDに「-1」を指定するとテーブル内のすべてのページが出力されます。

dbcc traceon(3604)
dbcc ind('testdb1','tl',-1)
go
dbceindコマンド実行結果

ページ内の確認

dbccpageコマンドを使用してページの中を確認してみましょう。コマンドシンタックスは次のとおりです。

dbcc page(データベース名,ファイルID,ページID,出力オプション)

ファイルIDにはdbceindコマンドで出力されたPageFID列の値を指定します。ままた、ページIDには同じくPagePIDを指定します。出力オプションは「-1」から「3」までの値が指定できます。それでは、出力オプションによる結果の違いを確認していきましょう

a.出力オプション「-1」または「O」実行したコマンド:dbcc page(‘testdb1’,1,80,-1)またはdbccpage(db1,1,80,0)

LIST3のように、ページ内の管理情報のみが出力されます。今回のテーブルはヒープなので、下線1の箇所にインデックスIDとして0が出力されています。下線2ではオブジェクトIDが確認できます。また、もしインデックスページに対してこのコマンドを実行した場合は、下線3および下線4に関連するページIDが出力されます。

LIST3:ページ内の管理情報

ページ内の管理情報図

実行結果

PAGE: (1:80)


BUFFER:


BUF @0x00000210C6DDD140

bpage = 0x0000021016BE2000          bPmmpage = 0x0000000000000000       bsort_r_nextbP = 0x00000210C6DDD090
bsort_r_prevbP = 0x0000000000000000 bhash = 0x0000000000000000          bpageno = (1:80)
bpart = 0                           bstat = 0x9                         breferences = 0
berrcode = 0                        bUse1 = 63725                       bstat2 = 0x0
blog = 0x15ab215a                   bsampleCount = 0                    bIoCount = 0
resPoolId = 0                       bcputicks = 0                       bReadMicroSec = 169
bDirtyPendingCount = 0              bDirtyContext = 0x0000000000000000  bDbPageBroker = 0x0000000000000000
bdbid = 7                           bpru = 0x000002100FF28040           

PAGE HEADER:


Page @0x0000021016BE2000

m_pageId = (1:80)                   m_headerVersion = 1                 m_type = 10
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 50    m_indexId (AllocUnitId.idInd) = 3   Metadata: AllocUnitId = 844424933408768
Metadata: PartitionId = 844424933408768                                  Metadata: IndexId = 3
Metadata: ObjectId = 50             m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 90                        m_slotCnt = 2                       m_freeCnt = 6
m_freeData = 8182                   m_reservedCnt = 0                   m_lsn = (38:1080:235)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1466618266            DB Frag ID = 1                      

Allocation Status

<span class="marker-under-red">GAM (1:2)</span><span class="marker-under-red">⑤</span><span class="marker-under-red"> = ALLOCATED               SGAM (1:3) ⑥= ALLOCATED              PFS (1:1) ⑦= 0x30 IAM_PG MIXED_EXT   0_PCT_FULL</span>
DIFF (1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           


DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。

完了時刻: 2024-02-19T15:13:22.2568501+09:00

下線5と下線6には前章で取り上げたGAMとSGAMに関する情報が出力されています。つまり、出力されているGAM/SGAMページに、このページが含まれるエクステントの管理情報が存在することを意味しています。また、下線7も同じく前章に登場したPFSに関する情報です。「MIXED_EXTALLOCATED」から、このページが混合エクステントに割り当てられていることが確認できます。また、「50_PCT_FULL」からは、ページの使用率が約50%であることを認識できます。

b.出力オプション:「1」実行したコマンド:dbcc page(‘testdb1’,1,80,1)

LIST4のように、ヘッダー情報に加えて実際のデータ部分の内容が出力されます(ヘッダー部分の出力内容は、前述のと同じなので解説は省略します)。データ部分の情報は、ページ内に格納されている各行ごとに出力されます。各行はSlotとして表現され、ページ最後尾のオフセットテーブルの番号と対応しています。実データは16進数で表現され、16バイトごとに成型されています。各行の右部分に表示可能な文字列などが出力されています。

LIST4:データ部分の内容

データ部分の内容

実行結果

PAGE: (1:80)


BUFFER:


BUF @0x00000210C6DDD140

bpage = 0x0000021016BE2000          bPmmpage = 0x0000000000000000       bsort_r_nextbP = 0x00000210C6DDD090
bsort_r_prevbP = 0x0000000000000000 bhash = 0x0000000000000000          bpageno = (1:80)
bpart = 0                           bstat = 0x9                         breferences = 0
berrcode = 0                        bUse1 = 63953                       bstat2 = 0x0
blog = 0x15ab215a                   bsampleCount = 0                    bIoCount = 0
resPoolId = 0                       bcputicks = 0                       bReadMicroSec = 169
bDirtyPendingCount = 0              bDirtyContext = 0x0000000000000000  bDbPageBroker = 0x0000000000000000
bdbid = 7                           bpru = 0x000002100FF28040           

PAGE HEADER:


Page @0x0000021016BE2000

m_pageId = (1:80)                   m_headerVersion = 1                 m_type = 10
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 50    m_indexId (AllocUnitId.idInd) = 3   Metadata: AllocUnitId = 844424933408768
Metadata: PartitionId = 844424933408768                                  Metadata: IndexId = 3
Metadata: ObjectId = 50             m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 90                        m_slotCnt = 2                       m_freeCnt = 6
m_freeData = 8182                   m_reservedCnt = 0                   m_lsn = (38:1080:235)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1466618266            DB Frag ID = 1                      

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED              PFS (1:1) = 0x30 IAM_PG MIXED_EXT   0_PCT_FULL
DIFF (1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           

DATA:


Slot 0, Offset 0x60, Length 94, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =                 Record Size = 94

Memory Dump @0x000000E2D81F6060

0000000000000000:   00005e00 00000000 00000000 00000000 00000000  ..^.................
0000000000000014:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000028:   00000000 01000000 00000000 00000000 00000000  ....................
000000000000003C:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000050:   00000000 00000000 00000000 0000               ..............

Slot 1, Offset 0xbe, Length 7992, DumpStyle BYTE

Record Type = PRIMARY_RECORD        Record Attributes =                 Record Size = 7992

Memory Dump @0x000000E2D81F60BE

0000000000000000:   0000381f 00000000 00000000 00000000 00000000  ..8.................
0000000000000014:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000028:   00000000 00000000 00000000 00000000 00000000  ....................
000000000000003C:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000050:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000064:   00000000 00000000 00000000 00000000 00000000  ....................
0000000000000078:   00000000 00000000 00000000 00000000 00000000  ....................
000000000000008C:   00000000 00000000 00000000 00000000 00000000  ....................
00000000000000A0:   00000000 00000000 00000000 00000000 00000000  ....................
00000000000000B4:   00000000 00000000 00000000 00000000 00000000  ....................
00000000000000C8:   00000000 00000000 00000000 00000000 00000000  ....................
00000000000000DC:   00000000 00000000 00000000 00000000 00000000  ....................
00000000000000F0:   00000000 00000000 00000000 00000000 00000000  ....................
~
0000000000001F2C:   00000000 00000000 00000000                    ............


DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。

完了時刻: 2024-02-19T15:17:10.2259508+09:00

c.出力オプション:「2」実行したコマンド:dbcc page(‘testdb1’,1,80,2)

出力オプション「2」を指定すると、単純にページの内容は16進数のダンプとして出力されます(LIST5)。16バイトが1行として成型され、1ページ分(8KB)すべての内容が出力されます。併せて、表示可能な文字は右側部分に出力されます。準備段階で挿入した、「AAA」や「BBB」といった文字列を確認できます。また、ヘッダー部分の情報も出力されますが、内容は前述のaと同じなので解説は割愛します。

d.出力オプション:「3」実行したコマンド:dbcc page(‘db1’,1,80,3)

出力オプション「3」では、出力オプション「1」の内容に加えて各列の名前や、格納している値が、それぞれの行ごとに成型されて出力されてます。そのため、最も理解しやすい出力形式であると言えます。

dbcc page実行結果

実行結果

PAGE: (1:80)


BUFFER:


BUF @0x00000210C6DDD140

bpage = 0x0000021016BE2000          bPmmpage = 0x0000000000000000       bsort_r_nextbP = 0x00000210C6DDD090
bsort_r_prevbP = 0x0000000000000000 bhash = 0x0000000000000000          bpageno = (1:80)
bpart = 0                           bstat = 0x9                         breferences = 0
berrcode = 0                        bUse1 = 64357                       bstat2 = 0x0
blog = 0x15ab215a                   bsampleCount = 0                    bIoCount = 0
resPoolId = 0                       bcputicks = 0                       bReadMicroSec = 169
bDirtyPendingCount = 0              bDirtyContext = 0x0000000000000000  bDbPageBroker = 0x0000000000000000
bdbid = 7                           bpru = 0x000002100FF28040           

PAGE HEADER:


Page @0x0000021016BE2000

m_pageId = (1:80)                   m_headerVersion = 1                 m_type = 10
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 50    m_indexId (AllocUnitId.idInd) = 3   Metadata: AllocUnitId = 844424933408768
Metadata: PartitionId = 844424933408768                                  Metadata: IndexId = 3
Metadata: ObjectId = 50             <span class="marker-under-red">m_prevPage = (0:0)</span><span class="marker-under-red">③</span><span class="marker-under-red">                  m_nextPage = (0:0)</span>④
pminlen = 90                        m_slotCnt = 2                       m_freeCnt = 6
m_freeData = 8182                   m_reservedCnt = 0                   m_lsn = (38:1080:235)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1466618266            DB Frag ID = 1                      

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED              PFS (1:1) = 0x30 IAM_PG MIXED_EXT   0_PCT_FULL
DIFF (1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           

DATA:


Memory Dump @0x000000E2D8BF6000

000000E2D8BF6000:   010a0000 00020300 00000000 00005a00 00000000  ..............Z.....
000000E2D8BF6014:   00000200 32000000 0600f61f 50000000 01000000  ....2.......P.......
000000E2D8BF6028:   26000000 38040000 eb000000 00000000 00000000  &...8...............
000000E2D8BF603C:   662e95a8 00000000 00000000 00000000 00000000  f..¨................
000000E2D8BF6050:   00000000 00000000 00000000 00000000 00005e00  ..................^.
000000E2D8BF6064:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF6078:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF608C:   01000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF60A0:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF60B4:   00000000 00000000 00000000 381f0000 00000000  ............8.......
000000E2D8BF60C8:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF60DC:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF60F0:   00000000 00000000 00000000 00000000 00000000  ....................

~
000000E2D8BF7F7C:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7F90:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7FA4:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7FB8:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7FCC:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7FE0:   00000000 00000000 00000000 00000000 00000000  ....................
000000E2D8BF7FF4:   00000000 21212121 be006000                    ....!!!!¾.`.


DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。

完了時刻: 2024-02-19T15:23:54.1208732+09:00

c.出力オプション:「3」実行したコマンド:dbcc page(‘testdb1’,1,80,3)

出力オプション「3」では、出力オプション「1」の内容に加えて各列の名前や、格納している値が、それぞれの行ごとに成型されて出力されます。(LIST6)そのため、最も理解しやすい出力形式であると言えます。

dbcc page実行結果

実行結果

PAGE: (1:80)


BUFFER:


BUF @0x00000210C6DDD140

bpage = 0x0000021016BE2000          bPmmpage = 0x0000000000000000       bsort_r_nextbP = 0x00000210C6DDD090
bsort_r_prevbP = 0x0000000000000000 bhash = 0x0000000000000000          bpageno = (1:80)
bpart = 0                           bstat = 0x9                         breferences = 0
berrcode = 0                        bUse1 = 64617                       bstat2 = 0x0
blog = 0x15ab215a                   bsampleCount = 0                    bIoCount = 0
resPoolId = 0                       bcputicks = 0                       bReadMicroSec = 169
bDirtyPendingCount = 0              bDirtyContext = 0x0000000000000000  bDbPageBroker = 0x0000000000000000
bdbid = 7                           bpru = 0x000002100FF28040           

PAGE HEADER:


Page @0x0000021016BE2000

m_pageId = (1:80)                   m_headerVersion = 1                 m_type = 10
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 50    m_indexId (AllocUnitId.idInd) = 3   Metadata: AllocUnitId = 844424933408768
Metadata: PartitionId = 844424933408768                                  Metadata: IndexId = 3
Metadata: ObjectId = 50             m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 90                        m_slotCnt = 2                       m_freeCnt = 6
m_freeData = 8182                   m_reservedCnt = 0                   m_lsn = (38:1080:235)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1466618266            DB Frag ID = 1                      

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED              PFS (1:1) = 0x30 IAM_PG MIXED_EXT   0_PCT_FULL
DIFF (1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           

IAM: Header @0x000000E2DB9F6064 Slot 0, Offset 96

sequenceNumber = 0                  status = 0x0                        objectId = 0
indexId = 0                         page_count = 0                      start_pg = (1:0)


IAM: Single Page Allocations @0x000000E2DB9F608E

Slot 0 = (0:0)                      Slot 1 = (0:0)                      Slot 2 = (0:0)
Slot 3 = (0:0)                      Slot 4 = (0:0)                      Slot 5 = (0:0)
Slot 6 = (0:0)                      Slot 7 = (0:0)                      


IAM: Extent Alloc Status Slot 1 @0x000000E2DB9F60C2

(1:0)        - (1:1016)     = NOT ALLOCATED                              


DBCC の実行が完了しました。DBCC がエラー メッセージを出力した場合は、システム管理者に相談してください。

完了時刻: 2024-02-19T15:28:13.5797383+09:00