這篇文章我想談下SQL Server如何在變長(zhǎng)列上存儲(chǔ)索引。首先我們創(chuàng)建一個(gè)包含變長(zhǎng)列的表,在上面定義主鍵,即在上面定義了聚集索引,然后往里面插入80000條記錄:
1 -- Create a new table 2 CREATE TABLE Customers 3 ( 4 CustomerName VARCHAR(255) NOT NULL PRIMARY KEY, 5 Filler CHAR(138) NOT NULL 6 ) 7 GO 8 9 -- Insert 80.000 records10 DECLARE @i INT = 111 WHILE (@i <= 80000)12 BEGIN13 INSERT INTO Customers VALUES14 (15 'CustomerName' + CAST(@i AS VARCHAR),16 'Filler' + CAST(@i AS VARCHAR)17 )18 19 SET @i += 120 END21 GO
從代碼里我們可以看到,我在VARCHAR(255)列上建立了主鍵約束,SQL Server會(huì)強(qiáng)制這列為唯一聚集索引。接下來(lái)我們通過(guò)DMV sys.dm_db_index_physical_stats來(lái)獲取聚集索引的相關(guān)物理信息:
1 -- Retrieve physical information about the clustered index 2 SELECT * FROM sys.dm_db_index_physical_stats 3 ( 4 DB_ID('ALLOCATIONDB'), 5 OBJECT_ID('Customers'), 6 NULL, 7 NULL, 8 'DETAILED' 9 )10 GO
從輸出結(jié)果可以看出,在索引頁(yè)里,min_record_size_in_bytes列的值是7,max_record_size_in_bytes列的值是28。我們據(jù)此可以得出結(jié)論:在索引記錄內(nèi)部,聚集鍵是以變長(zhǎng)列保存的。我們建立一個(gè)幫助表來(lái)存儲(chǔ)DBCC IND的輸出信息來(lái)做進(jìn)一步分析。
1 -- Create a helper table 2 CREATE TABLE HelperTable 3 ( 4 PageFID TINYINT, 5 PagePID INT, 6 IAMFID TINYINT, 7 IAMPID INT, 8 ObjectID INT, 9 IndexID TINYINT,10 PartitionNumber TINYINT,11 PartitionID BIGINT,12 iam_chain_type VARCHAR(30), 13 PageType TINYINT, 14 IndexLevel TINYINT,15 NextPageFID TINYINT,16 NextPagePID INT,17 PrevPageFID INT,18 PrevPagePID INT, 19 PRIMARY KEY (PageFID, PagePID)20 )21 GO22 23 -- Write everything in a table for further analysis24 INSERT INTO HelperTable EXEC('DBCC IND(ALLOCATIONDB, Customers, 1)')25 GO26 27 -- Retrieve the root index page (1 page)28 SELECT * FROM HelperTable29 WHERE IndexLevel = 230 GO
我這里的根頁(yè)是15058,我們使用DBCC PAGE命令查看下這個(gè)根頁(yè)(記得先執(zhí)行 DBCC TRACEON(3604))。
1 DBCC TRACEON (3604)2 GO3 --Dump out the root index page4 DBCC PAGE(ALLOCATIONDB, 1, 15058, 1)5 GO
即如下所示的數(shù)字:
00000000: 269d3b00 00010001 001b0043 7573746f †&.;........Custo 00000010: 6d65724e 616d6531 333533†††††††††††††merName1353
我們來(lái)分析下這些16進(jìn)制值:26 95020000 0100 0100 1b00 43757374 6f6d6572 4e616d65 31333533
從上面的解釋?zhuān)覀兛梢钥闯鯯QL Server存儲(chǔ)變長(zhǎng)索引列格式和數(shù)據(jù)頁(yè)里存儲(chǔ)變長(zhǎng)列格式是一樣的。但你要知道有一點(diǎn)額外開(kāi)銷(xiāo),因?yàn)槟阈枰~外2 bytes 來(lái)存儲(chǔ)變長(zhǎng)列個(gè)數(shù),對(duì)于每個(gè)變長(zhǎng)列在變長(zhǎng)列偏移數(shù)組里需要2 bytes。在設(shè)計(jì)索引和計(jì)算一個(gè)索引頁(yè)存放多少索引記錄時(shí),要留意這些存儲(chǔ)開(kāi)銷(xiāo)。
新聞熱點(diǎn)
疑難解答
圖片精選