zoukankan      html  css  js  c++  java
  • 堆表的在执行Select语句时的默认排序问题——分析问题

    首先,看了一下出库单主表的数据结构,出库单主表中既没有主键也没有索引,经过分析原因如下:

    对于Sql Server 执行计划没有带索引的表,select返回记录的顺序和堆表扫描返回的顺序相同。通过扫描 IAM 页可以对堆集进行表扫描或串行读,以找到容纳这个堆集的页的扩展盘区。因为 IAM 按扩展盘区在数据文件内存在的顺序表示它们,意味着堆集中的行一般不按照插入的顺序返回。堆表(heap table)数据插入时时存储位置是随机的,主要是数据库内部块的空闲情况决定,获取数据是按照命中率计算,全表扫表时不见得先插入的数据先查到

    没有聚集索引的表称作堆数据表(heap table。即数据行不按任何特殊的顺序存储,数据页也没有任何特殊的顺序。数据页不在链接列表内链接。 SQL Server 使用 IAM 页在堆中移动。堆内的数据页和行没有任何特定的顺序,也不链接在一起。数据页之间唯一的逻辑连接是记录在 IAM 页内的信息。

     

    接下来说一下IAM,IAMIndex Allocation Map,索引分配映射)页用来跟踪单个文件中约4G大小的空间,跟踪的空间是按4G字节对齐。被跟踪的这4G大小的页被称为“GAM区间”(GAM Interval)。IAM页所跟踪的GAM区间中的空间是属于同一对象的。

    因为IAM只是跟踪单个文件里的一个GAM区间里的空间。若一个数据库包括多个文件,或者一些文件大小超过4G,并且实体分配的空间恰好跨越多个文件或跨越一个文件的多个GAM区间,那么你就会看到为了跟踪单个实体的所有空间是如何使用多个IAM页的了。

    这时就要用到IAM链了。它是一个IAM页的链表,该链表将所有用来跟踪同一实体的分配空间的所有IAM页链接在一起。该链表并不排序,当需要一个新的IAM页时便添加进链表。链表中的IAM页是编号的,这个编号也是按添加时的顺序增加的。

    IAM页头部还有一个单页的数组。这只是在IAM链中的第一个IAM页中,这个数组只存在IAM 链中的第一个页中(因为整个IAM 链中只需要跟踪8 个单独分配的页)而不是区(一个区是8个连续的页)的。(注:前8页是按页在混合区中分配的;超过8个页后才开始按区分配)

     

    IAM: Single Page Allocations @0x3D4FC08E(单页分配数组)

    Slot 0 = (1:946)              Slot 1 = (1:1697)                    Slot 2 = (1:804)

    Slot 3 = (1:184)              Slot 4 = (1:949)                     Slot 5 = (1:816)

    Slot 6 = (1:3168)             Slot 7 = (1:1348) 

     

    你会发现上面Slot0---Slot7把所有的单页分配数组都已经满了 , 然后转向分配统一区。第一个有效的区开始于3200页,一直到3208页开始的区。如下。

    IAM: Extent Alloc Status Slot 1 @0x3D4FC0C2

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

    (1:3200)     -              =     ALLOCATED           

    (1:3208)     - (1:3776)     = NOT ALLOCATED   

     

    关于IAM 页还要注意两件事:

    · IAM页是从混合区中分配而来的,且这些页不受监控。

    · 一个文件中分配的IAM 也可以用来跟踪另一个文件的区。

     

    使用DBCC IND(数据库,T_EPZ_DELIVERY_OUT,1)查询可以得到下面的数据页的排序(如图1),则也就可以得到相应的查询记录的排序结果。如图2.

                                           图1

    没有主键值时的默认查询顺序。通过以上分析可以得出,它是根据IAM页中的顺序进行默认排序的。如下图

     

                                                             图2

    下面我们将了解数据库中数据页的结构。

     

    我们可以通过以下命令来查看:

     go

     DBCC  TRACEON(3604)

    go

     dbcc page(数据库,1,3168,3)

     go

     dbcc page(数据库,1,3200,3)

     

     

    PAGE: (1:3168)

    --------------

    BUFFER:

    -------

    BUF @0x016AAE00

    ---------------

    bpage = 0x1B260000        bhash = 0x00000000        bpageno = (1:3168)

    bdbid = 8                 breferences = 1           bstat = 0x9

    bspin = 0                 bnext = 0x00000000     

    PAGE HEADER:

    ------------

    Page @0x1B260000

    ----------------

    m_pageId = (1:3168)       m_headerVersion = 1       m_type = 1

    m_typeFlagBits = 0x0      m_level = 0               m_flagBits = 0x8

    m_objId = 1285579618      m_indexId = 0             m_prevPage = (0:0)

    m_nextPage = (0:0)        pminlen = 69              m_slotCnt = 20

    m_freeCnt = 2724          m_freeData = 7144         m_reservedCnt = 0

    m_lsn = (940:328:2)       m_xactReserved = 0        m_xdesId = (0:214337)

    m_ghostRecCnt = 0         m_tornBits = 291662041    

     

    Allocation Status

    -----------------

    GAM (1:2) = ALLOCATED     SGAM (1:3) = ALLOCATED    

    PFS (1:1) = 0x22 MIXED_EXT  80_PCT_FULL             DIFF (1:6) = CHANGED

    ML (1:7) = NOT MIN_LOGGED 

     

    Slot 0 Offset 0x60

    ------------------

    DELIVERY_NO                      = BE404942550159           

     

    Slot 1 Offset 0x19e

    -------------------

    DELIVERY_NO                      = BE404942550160          

     

    Slot 2 Offset 0x2dc

    -------------------

    DELIVERY_NO                      = BE404942550161             

     

    Slot 3 Offset 0x41a

    -------------------

    DELIVERY_NO                      = BE404942550162           

     

    Slot 4 Offset 0x1ac6

    --------------------

    DELIVERY_NO                      = BE404942550169         

     

    Slot 5 Offset 0x19a4

    --------------------

    DELIVERY_NO                      = BE404942550170               

     

    Slot 6 Offset 0x1882

    --------------------

    DELIVERY_NO                      = BE404942550171               

     

    Slot 7 Offset 0x1760

    --------------------

    DELIVERY_NO                      = BE404942550172        

     

    Slot 8 Offset 0x163e

    --------------------

    DELIVERY_NO                      = BE404942550173   

     

    Slot 9 Offset 0x151c

    --------------------

    DELIVERY_NO                      = BE404942550174           

     

    Slot 10 Offset 0x13fa

    ---------------------

    DELIVERY_NO                      = BE404942550175   

     

    Slot 11 Offset 0x12d8

    ---------------------

    DELIVERY_NO                      = BE404942550176   

     

    Slot 12 Offset 0x11b6

    ---------------------

    DELIVERY_NO                      = BE404942550177   

     

    Slot 13 Offset 0x1094

    ---------------------

    DELIVERY_NO                      = BE404942550178   

     

    Slot 14 Offset 0xf72

    --------------------

    DELIVERY_NO                      = BE404942550163   

    Slot 15 Offset 0xe50

    --------------------

    DELIVERY_NO                      = BE404942550164   

     

    Slot 18 Offset 0xd2e

    --------------------

    DELIVERY_NO                      = BE404942550167   

    Slot 19 Offset 0xc0c

    --------------------

    DELIVERY_NO                      = BE404942550168   

     

     -----------------------------------------------------第二页---------------------------------

    PAGE: (1:3200)

    --------------

    BUFFER:

    -------

    BUF @0x016AAC00

    ---------------

    bpage = 0x1B250000        bhash = 0x00000000        bpageno = (1:3200)

    bdbid = 8                 breferences = 1           bstat = 0x9

    bspin = 0                 bnext = 0x00000000        

     

    PAGE HEADER:

    ------------

    Page @0x1B250000

    ----------------

    m_pageId = (1:3200)       m_headerVersion = 1       m_type = 1

    m_typeFlagBits = 0x0      m_level = 0               m_flagBits = 0x8000

    m_objId = 1285579618      m_indexId = 0             m_prevPage = (0:0)

    m_nextPage = (0:0)        pminlen = 69              m_slotCnt = 2

    m_freeCnt = 7512          m_freeData = 676          m_reservedCnt = 0

    m_lsn = (939:344:3)       m_xactReserved = 0        m_xdesId = (0:0)

    m_ghostRecCnt = 0         m_tornBits = 12289        

     

    Allocation Status

    -----------------

    GAM (1:2) = NOT ALLOCATED SGAM (1:3) = NOT ALLOCATED

    PFS (1:1) = 0x1  50_PCT_FULL                        DIFF (1:6) = CHANGED

    ML (1:7) = NOT MIN_LOGGED 

     

    Slot 0 Offset 0x60

    ------------------

    DELIVERY_NO                      = BE404942550166   

     

    Slot 1 Offset 0x182

    -------------------

    DELIVERY_NO                      = BE404942550165   

     

    从上面的数据页中的结构来看,每一页相对应的Slot所记录的数据与在数据库中查询出来的顺序一样。

     

  • 相关阅读:
    关于 log4j.additivity
    JDK8新特性:使用Optional:解决NPE问题的更干净的写法
    异常处理和日志输出使用小结
    搭建DNS服务器
    git 使用技巧
    mysql
    linux学习记录
    nginx解析
    node npm pm2命令简析
    jenkins使用简析
  • 原文地址:https://www.cnblogs.com/chillsrc/p/2535194.html
Copyright © 2011-2022 走看看