更新INCLUDE indexes中的非键列会引起索引碎片吗?

今天跟CareySon 讨论有些索引碎片的一个事情,他发现下面一篇文章中的有些问题,所以我做了个简单测试,如有不妥,欢迎大家批评指点。

http://www.daveturpin.com/2010/04/composite-index-vs-include-covering-index/

也就是更新INCLUDE indexes中的非键列会引起索引碎片吗?

 测试代码如下:

 

CREATE TABLE sp_tablepages
(PageFID tinyint,
PagePID int,
IAMFID tinyint,
IAMPID int,
ObjectID int,
IndexID tinyint,
PartitionNumber tinyint,
PartitionID bigint,
iam_chain_type varchar(30),
PageType tinyint,
IndexLevel tinyint,
NextPageFID tinyint,
NextPagePID int,
PrevPageFID tinyint,
PrevPagePID int,
Primary Key (PageFID, PagePID));

go

 

CREATE TABLE bigrows
(
a int ,
b varchar(6400)
);
GO
/****** Object:  Index [NonClusteredIndex]    Script Date: 2012/5/18 15:05:12 ******/
CREATE NONCLUSTERED INDEX [NonClusteredIndex] ON [dbo].[bigrows]
(
 [a] ASC
)
INCLUDE (  [b]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO

/* Insert five rows into the table */
INSERT INTO bigrows
VALUES (5, REPLICATE('a', 1550));
INSERT INTO bigrows
VALUES (10, replicate('b', 1550));
INSERT INTO bigrows
VALUES (15, replicate('c', 1550));
INSERT INTO bigrows
VALUES (20, replicate('d', 1550));
INSERT INTO bigrows
VALUES (25, replicate('e', 1550));
--INSERT INTO bigrows
--VALUES (26, replicate('f', 1600));
GO
TRUNCATE TABLE sp_tablepages;
INSERT INTO sp_tablepages
EXEC ('DBCC IND ( DDDD, 1333579789,  2 )' );
GO

--上面的DDDD, 1333579789 分别为数据库的NAME跟INDEX的ID

TRUNCATE TABLE sp_tablepages;
INSERT INTO sp_tablepages
EXEC ('DBCC IND ( DDDD, 1349579846,  2 )' );
GO
SELECT *
FROM sp_tablepages where pagetype =2 and indexlevel=0

 

结果如下:

pagepid pagetype indexlevel
420            2           0

 

看一下那个页面里包含什么东西:

执行
DBCC TRACEON(3604);
GO
DBCC PAGE(DDDD, 1, 420, 1);
GO

DBCC execution completed. If DBCC printed error messages, contact your system administrator.

PAGE: (1:420)


BUFFER:


BUF @0x04686868

bpage = 0x10D5C000                  bhash = 0x00000000                  bpageno = (1:420)
bdbid = 10                          breferences = 0                     bcputicks = 0
bsampleCount = 0                    bUse1 = 21914                       bstat = 0x10b
blog = 0xcc7acccc                   bnext = 0x00000000                 

PAGE HEADER:


Page @0x10D5C000

m_pageId = (1:420)                  m_headerVersion = 1                 m_type = 2
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8000
m_objId (AllocUnitId.idObj) = 122   m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594045923328                               
Metadata: PartitionId = 72057594041532416                                Metadata: IndexId = 2
Metadata: ObjectId = 1349579846     m_prevPage = (0:0)                  m_nextPage = (0:0)
pminlen = 13                        m_slotCnt = 5                       m_freeCnt = 236
m_freeData = 7946                   m_reservedCnt = 0                   m_lsn = (42:221:4)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = 0                      DB Frag ID = 1                     

Allocation Status

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

DATA:


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

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0F8FA060

00000000:   36050000 00a20100 00010000 00030000 01002206  6.................".
00000014:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
00000028:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
0000003C:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa

---------------------- 此处省略

000005F0:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
00000604:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
00000618:   61616161 61616161 6161                        aaaaaaaaaa    

Slot 1, Offset 0x682, Length 1570, DumpStyle BYTE

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0F8FA682

00000000:   360a0000 00a20100 00010001 00030000 01002206  6.................".
00000014:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb
00000028:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb
 00000550:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb

----------------------此处省略

000005F0:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb
00000604:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb
00000618:   62626262 62626262 6262                        bbbbbbbbbb    

Slot 2, Offset 0xca4, Length 1570, DumpStyle BYTE

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0F8FACA4

00000000:   360f0000 00a20100 00010002 00030000 01002206  6.................".
00000014:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc
00000028:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc

---------------------- 此处省略

000005F0:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc
00000604:   63636363 63636363 63636363 63636363 63636363  cccccccccccccccccccc
00000618:   63636363 63636363 6363                        cccccccccc    

Slot 3, Offset 0x12c6, Length 1570, DumpStyle BYTE

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0F8FB2C6

00000000:   36140000 00a20100 00010003 00030000 01002206  6.................".
00000014:   64646464 64646464 64646464 64646464 64646464  dddddddddddddddddddd
00000028:   64646464 64646464 64646464 64646464 64646464  dddddddddddddddddddd
---------------------- 此处省略

000005F0:   64646464 64646464 64646464 64646464 64646464  dddddddddddddddddddd
00000604:   64646464 64646464 64646464 64646464 64646464  dddddddddddddddddddd
00000618:   64646464 64646464 6464                        dddddddddd    

Slot 4, Offset 0x18e8, Length 1570, DumpStyle BYTE

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0F8FB8E8

00000000:   36190000 00a20100 00010004 00030000 01002206  6.................".
00000014:   65656565 65656565 65656565 65656565 65656565  eeeeeeeeeeeeeeeeeeee
---------------------- 此处略微

000005F0:   65656565 65656565 65656565 65656565 65656565  eeeeeeeeeeeeeeeeeeee
00000604:   65656565 65656565 65656565 65656565 65656565  eeeeeeeeeeeeeeeeeeee
00000618:   65656565 65656565 6565                        eeeeeeeeee    

OFFSET TABLE:

Row - Offset                       
4 (0x4) - 6376 (0x18e8)            
3 (0x3) - 4806 (0x12c6)            
2 (0x2) - 3236 (0xca4)             
1 (0x1) - 1666 (0x682)             
0 (0x0) - 96 (0x60)                

好了,很明显,所以的数据在同一个索引页面里。

 

再看一下碎片的情况。

SET NOCOUNT ON
--Use the pubs database
USE DDDD
DBCC SHOWCONTIG (bigrows,NonClusteredIndex)-- WITH ALL_INDEXES
GO

 

DBCC SHOWCONTIG scanning 'bigrows' table...
Table: 'bigrows' (1349579846); index ID: 2, database ID: 10
LEAF level scan performed.
- Pages Scanned................................: 1
- Extents Scanned..............................: 1
- Extent Switches..............................: 0
- Avg. Pages per Extent........................: 1.0
- Scan Density [Best Count:Actual Count].......: 100.00% [1:1]
- Logical Scan Fragmentation ..................: 0.00%
- Extent Scan Fragmentation ...................: 0.00%
- Avg. Bytes Free per Page.....................: 236.0
- Avg. Page Density (full).....................: 97.08%
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 

Avg. Bytes Free per Page : 236.0, Avg. Page Density (full) : 97.08%,Logical Scan Fragmentation ..................: 0.00%

从这个参数来看应该不错,碎片不严重。

Avg. Page Density (full) : 97.08%

Logical Scan Fragmentation ..................: 0.00%

 

然后我们更新INCLUDE indexes中的非键列,看看是不是会引起索引碎片。

UPDATE  bigrows SET b= replicate('b', 2000)  WHERE A=10

再次运行

DBCC PAGE(DDDD, 1, 420, 1);

 


PAGE: (1:420)


BUFFER:


BUF @0x04686868

bpage = 0x10D5C000                  bhash = 0x00000000                  bpageno = (1:420)
bdbid = 10                          breferences = 0                     bcputicks = 0
bsampleCount = 0                    bUse1 = 22474                       bstat = 0x9
blog = 0x7acccc7a                   bnext = 0x00000000                 

PAGE HEADER:


Page @0x10D5C000

m_pageId = (1:420)                  m_headerVersion = 1                 m_type = 2
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x200
m_objId (AllocUnitId.idObj) = 122   m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594045923328                               
Metadata: PartitionId = 72057594041532416                                Metadata: IndexId = 2
Metadata: ObjectId = 1349579846     m_prevPage = (0:0)                  m_nextPage = (1:412)
pminlen = 13                        m_slotCnt = 2                       m_freeCnt = 4502
m_freeData = 5256                   m_reservedCnt = 0                   m_lsn = (42:255:43)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = -1654904262            DB Frag ID = 1                     

Allocation Status

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

DATA:


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

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 1570                 
Memory Dump @0x0724C060

00000000:   36050000 00a20100 00010000 00030000 01002206  6.................".
00000014:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
00000028:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa

 

---------------------- 此处省略

 00000604:   61616161 61616161 61616161 61616161 61616161  aaaaaaaaaaaaaaaaaaaa
00000618:   61616161 61616161 6161                        aaaaaaaaaa    

Slot 1, Offset 0xca4, Length 2020, DumpStyle BYTE

Record Type = INDEX_RECORD          Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS
Record Size = 2020                 
Memory Dump @0x0724CCA4

00000000:   360a0000 00a20100 00010001 00030000 0100e407  6...................
00000014:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb

 

---------------------- 此处省略

000007D0:   62626262 62626262 62626262 62626262 62626262  bbbbbbbbbbbbbbbbbbbb

OFFSET TABLE:

Row - Offset                       
1 (0x1) - 3236 (0xca4)             
0 (0x0) - 96 (0x60)                


DBCC execution completed. If DBCC printed error messages, contact your system administrator.
可以明显的看到420页面中的C,D,E数据已经移到了新的页面。

 

 

再看一下碎片的情况。

SET NOCOUNT ON
--Use the pubs database
USE DDDD
DBCC SHOWCONTIG (bigrows,NonClusteredIndex)-- WITH ALL_INDEXES
GO

 

 

DBCC SHOWCONTIG scanning 'bigrows' table...
Table: 'bigrows' (1349579846); index ID: 2, database ID: 10
LEAF level scan performed.
- Pages Scanned................................: 2
- Extents Scanned..............................: 2
- Extent Switches..............................: 1
- Avg. Pages per Extent........................: 1.0
- Scan Density [Best Count:Actual Count].......: 50.00% [1:2]
- Logical Scan Fragmentation ..................: 50.00%
- Extent Scan Fragmentation ...................: 0.00%
- Avg. Bytes Free per Page.....................: 3941.0
- Avg. Page Density (full).....................: 51.31%
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

 

Avg. Bytes Free per Page : 3941.0, Avg. Page Density (full) :51.31%,Logical Scan Fragmentation ..................: 50.00%

从这个参数来看,更新INCLUDE indexes中的非键列明显产生了碎片(包括 Avg. Page Density (full),Logical Scan Fragmentation )。
第一次写技术博文,并且我对索引碎片的理解也是刚开始研究,写的不大好,希望各位多见谅。

 

顺便说一下,SQL SERVER 只有2个碎片类型: Avg. Page Density (full) 跟 Logical Scan Fragmentation(Extent Scan Fragmentation 其实也属于逻辑碎片),

神马内部碎片,外部碎片都是山寨的说法,不受官方文档的支持。

posted on 2012-05-18 16:03  暖风的风  阅读(1062)  评论(7编辑  收藏  举报

导航