zoukankan      html  css  js  c++  java
  • 更新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 其实也属于逻辑碎片),

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

  • 相关阅读:
    sql 行列转换之关键字pivot,unpivot
    构建动态表达式(初级)
    HttpApplication事件执行顺序
    【转】delegate.BeginInvoke 注意事项
    Jquery.extend函数详解【转】
    【转】NET中反射实现 可空类型 与基础类型的转换 以及获取指定属性的大小问题
    sql执行字符串
    Javascript获取浏览器地址栏url各项值
    你妹的浏览器DNS缓存
    LazyLoad 延迟加载图片的jQuery插件介绍
  • 原文地址:https://www.cnblogs.com/WCFGROUP/p/2507940.html
Copyright © 2011-2022 走看看