各列を適切にサイズ設定します。各列に「標準」サイズを使用しないでください。30文字しか必要ない場合、なぜ255を処理できる列を作成するのですか?varchar(max)
文字列列に使用することを推奨していないのはとてもうれしいです。
これは、列にインデックスを作成する必要がある場合、または列を主キーとして使用しており、外部キー参照がある場合に特に賢明なアドバイスです。SQL Serverは、クエリオプティマイザーの各列のサイズを使用して、クエリ処理の推定メモリ要件を理解します。列のサイズが大きすぎると、パフォーマンスが低下する可能性があります。
サイズが大きい列のインデックスは、エラーが生成される可能性があります。
CREATE TABLE dbo.WideIndex
(
col1 varchar(255) NOT NULL
, col2 varchar(255) NOT NULL
, col3 varchar(600) NOT NULL
);
CREATE INDEX IX_WideIndex_01
ON dbo.WideIndex (col1, col2, col3);
上記のインデックスを作成しようとすると、次の警告が表示されます。
警告!キーの最大長は900バイトです。インデックス「IX_WideIndex_01」の最大長は1110バイトです。大きな値のいくつかの組み合わせでは、挿入/更新操作は失敗します。
900バイトは、クラスター化インデックス(およびSQL Server 2012以前の非クラスター化インデックス)の最大キーサイズです。SQL Serverの新しいバージョンの非クラスター化インデックスの最大キーサイズは1700バイトです。(255)などの一般的な幅の列を設計する場合、この警告が予想よりもはるかに多く発生する可能性があります。
ストレージ内部に興味がある場合は、次の小さなテストを使用して、SQL Serverが非圧縮行ストアデータを格納する方法をよりよく理解できます。
最初に、さまざまなサイズの列を格納できるテーブルを作成します。
IF OBJECT_ID(N'dbo.varchartest', N'U') IS NOT NULL
DROP TABLE dbo.varchartest;
GO
CREATE TABLE dbo.varchartest
(
varchar30 varchar(30) NOT NULL
, varchar255 varchar(255) NOT NULL
, varchar256 varchar(256) NOT NULL
);
次に、単一の行を挿入します。
INSERT INTO dbo.varchartest (varchar30, varchar255, varchar256)
VALUES (REPLICATE('1', 30), REPLICATE('2', 255), REPLICATE('3', 256));
このクエリは、ドキュメント化されていない、サポートされていない関数sys.fn_RowDumpCracker
を使用sys.fn_PhyslocCracker
して、テーブルに関する興味深い詳細を表示します。
SELECT rdc.*
, plc.*
FROM dbo.varchartest vct
CROSS APPLY sys.fn_RowDumpCracker(%%rowdump%%) rdc
CROSS APPLY sys.fn_physlocCracker(%%physloc%%) plc
出力は次のようになります。
╔=============================================== ======╦=============================================== ========╦=============╦=================╦======= ==╗
║partition_id col colName║IsInrow║IsSparse║IsRecordPrefixCompressed║IsSymbol║PrefixBytes║InRowLength║file_id║page_id║slot_id║
╠=============================================== ======╬=============================================== ========╬===============================╬======= ==╣
║1729382263096344576 var varchar30║1║0║0║0║0║30║1║1912║0║
║1729382263096344576║varchar255║1║0║0║0║0║255║1║1912║0║
║1729382263096344576 var varchar256║1║0║0║0║0║256║1║1912║0║
╚=============================================== ======╩=============================================== ========╩===============================╩======= ==╝
ご覧のとおりInRowLength
、各行の物理ストレージの場所( "file_id"、 "page_id"、および "slot_id")とともに各値が表示されます。
上記のクエリ結果からfile_id
and page_id
値を取得して実行するDBCC PAGE
と、実際の物理ページのコンテンツを確認できます。
DBCC TRACEON (3604); --send display to the client
DBCC PAGE (tempdb, 1, 1912, 3); --database, file_id, page_id, 3 to show page contents
DBCC TRACEOFF (3604);--reset display back to the error log
私のマシンの結果は次のとおりです。
ページ:(1:1912)
バッファ:
BUF @ 0x00000000FF5B2E80
bpage = 0x0000000024130000 bhash = 0x0000000000000000 bpageno =(1:1912)
bdbid = 2 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 32497 bstat = 0x10b
ブログ= 0x212121cc bnext = 0x0000000000000000
ページヘッダー:
ページ@ 0x0000000024130000
m_pageId =(1:1912)m_headerVersion = 1 m_type = 1
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x8000
m_objId(AllocUnitId.idObj)= 98834 m_indexId(AllocUnitId.idInd)= 7936
メタデータ:AllocUnitId = 2233785421652951040
メタデータ:PartitionId = 1945555045333008384メタデータ:IndexId = 0
メタデータ:ObjectId = 34099162 m_prevPage =(0:0)m_nextPage =(0:0)
pminlen = 4 m_slotCnt = 1 m_freeCnt = 7538
m_freeData = 652 m_reservedCnt = 0 m_lsn =(35:210971:362)
m_xactReserved = 0 m_xdesId =(0:0)m_ghostRecCnt = 0
m_tornBits = 0 DB Frag ID = 1
割り当てステータス
GAM(1:2)= ALLOCATED SGAM(1:3)= NOT ALLOCATED PFS(1:1)= 0x41 ALLOCATED 50_PCT_FULL
DIFF(1:6)=変更なしML(1:7)= NOT MIN_LOGGED
スロット0オフセット0x60長さ556
レコードタイプ= PRIMARY_RECORDレコード属性= NULL_BITMAP VARIABLE_COLUMNS
レコードサイズ= 556
メモリダンプ@ 0x000000005145A060
0000000000000000:30000400 03000003 002d002c 012c0231 31313131 0 ........-。、。、。11111
0000000000000014:31313131 31313131 31313131 31313131 31313131 11111111111111111111
0000000000000028:31313131 31323232 32323232 32323232 32323232 11111222222222222222
000000000000003C:32323232 32323232 32323232 32323232 32323232 22222222222222222222
0000000000000050:32323232 32323232 32323232 32323232 32323232 22222222222222222222
0000000000000064:32323232 32323232 32323232 32323232 32323232 22222222222222222222
0000000000000078:32323232 32323232 32323232 32323232 32323232 22222222222222222222
000000000000008C:32323232 32323232 32323232 32323232 32323232 22222222222222222222
00000000000000A0:32323232 32323232 32323232 32323232 32323232 22222222222222222222
00000000000000B4:32323232 32323232 32323232 32323232 32323232 22222222222222222222
00000000000000C8:32323232 32323232 32323232 32323232 32323232 22222222222222222222
00000000000000DC:32323232 32323232 32323232 32323232 32323232 22222222222222222222
00000000000000F0:32323232 32323232 32323232 32323232 32323232 22222222222222222222
0000000000000104:32323232 32323232 32323232 32323232 32323232 22222222222222222222
0000000000000118:32323232 32323232 32323232 32323232 32323232 22222222222222222222
000000000000012C:33333333 33333333 33333333 33333333 33333333 33333333333333333333333333333
0000000000000140:33333333 33333333 33333333 33333333 33333333 33333333333333333333 33333333
0000000000000154:33333333 33333333 33333333 33333333 33333333 33333333333333333333 33333333
0000000000000168:33333333 33333333 33333333 33333333 33333333 33333333333333333333 33333333
000000000000017C:33333333 33333333 33333333 33333333 33333333 33333333333333333333333333333
0000000000000190:33333333 33333333 33333333 33333333 33333333 33333333333333333333 33333333 33333333
00000000000001A4:33333333 33333333 33333333 33333333 33333333 33333333333333333333333
00000000000001B8:33333333 33333333 33333333 33333333 33333333 33333333333333333333333333333
00000000000001CC:33333333 33333333 33333333 33333333 33333333 33333333333333333333333333333
00000000000001E0:33333333 33333333 33333333 33333333 33333333 33333333333333333333333
00000000000001F4:33333333 33333333 33333333 33333333 33333333 33333333333333333333333333333
0000000000000208:33333333 33333333 33333333 33333333 33333333 33333333333333333333 33333333
000000000000021C:33333333 33333333 33333333 33333333 3333333333333333
スロット0列1オフセット0xf長さ30長さ(物理)30
varchar30 = 111111111111111111111111111111111
スロット0列2オフセット0x2d長さ255長さ(物理)255
varchar255 = 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222
スロット0列3オフセット0x12c長さ256長さ(物理)256
varchar256 = 3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
3333333333333333333333333333333333333333333333