Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 了解sp_spaceused值:保留和索引_大小_Sql Server_Allocation - Fatal编程技术网

Sql server 了解sp_spaceused值:保留和索引_大小

Sql server 了解sp_spaceused值:保留和索引_大小,sql-server,allocation,Sql Server,Allocation,我正在运行以下简单脚本: create table MyTable (filler char(10)) go insert into MyTable (filler) values ('a') go 1 exec sp_spaceused MyTable go drop table MyTable go 并得到如下结果: rows reserved data index_size unused ------ ---------- ------ -----------

我正在运行以下简单脚本:

create table MyTable (filler char(10))
go

insert into MyTable (filler) values ('a')
go 1

exec sp_spaceused MyTable
go

drop table MyTable
go
并得到如下结果:

rows   reserved   data   index_size    unused
------ ---------- ------ -----------   -------
1      72 KB      8 KB   8 KB          56 KB
我的问题是:

  • 为什么要保留72KB

  • 如果表甚至没有索引,为什么索引大小为8KB

  • 编辑:

    我想补充一点: 稍微更改脚本时:

    create table MyTable (filler char(69))
    go
    
    insert into MyTable (filler) values ('a')
    go 100
    
    我得到:

    rows   reserved   data   index_size    unused
    ------ ---------- ------ -----------   -------
    100    72 KB      16 KB   8 KB          48 KB
    
    请注意,将
    filler
    的大小定义为68字节(并插入100行)仍然会给出8KB作为
    数据的值(我们可以继续并将其设置为148字节,这将导致另一个8KB的增量,即24KB)

    你能帮我把计算结果分解一下吗?如果(显然)只使用了6900字节,那么8KB的增加是什么原因

    编辑#2: 以下是DBCC页面的结果:

    PAGE: (1:4392)
    
    
    BUFFER:
    
    
    BUF @0x00000000061A78C0
    
    bpage = 0x00000001EF3A8000          bhash = 0x0000000000000000          bpageno = (1:4392)
    bdbid = 6                           breferences = 0                     bcputicks = 0
    bsampleCount = 0                    bUse1 = 18482                       bstat = 0x9
    blog = 0x15ab215a                   bnext = 0x0000000000000000          bDirtyContext = 0x0000000000000000
    bstat2 = 0x0                        
    
    PAGE HEADER:
    
    
    Page @0x00000001EF3A8000
    
    m_pageId = (1:4392)                 m_headerVersion = 1                 m_type = 1
    m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x8200
    m_objId (AllocUnitId.idObj) = 260   m_indexId (AllocUnitId.idInd) = 256 
    Metadata: AllocUnitId = 72057594054967296                                
    Metadata: PartitionId = 72057594048151552                                Metadata: IndexId = 0
    Metadata: ObjectId = 1698105090     m_prevPage = (0:0)                  m_nextPage = (0:0)
    pminlen = 72                        m_slotCnt = 100                     m_freeCnt = 396
    m_freeData = 7596                   m_reservedCnt = 0                   m_lsn = (55:8224:2)
    m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
    m_tornBits = -2116084714            DB Frag ID = 1                      
    
    Allocation Status
    
    GAM (1:2) = ALLOCATED               SGAM (1:3) = NOT ALLOCATED          PFS (1:1) = 0x44 ALLOCATED 100_PCT_FULL
    DIFF (1:6) = CHANGED                ML (1:7) = NOT MIN_LOGGED           
    
    Slot 0 Offset 0x60 Length 75
    
    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP    Record Size = 75
    
    Memory Dump @0x0000000012A3A060
    
    0000000000000000:   10004800 61202020 20202020 20202020 20202020  ..H.a               
    0000000000000014:   20202020 20202020 20202020 20202020 20202020                      
    0000000000000028:   20202020 20202020 20202020 20202020 20202020                      
    000000000000003C:   20202020 20202020 20202020 010000                         ...
    
    Slot 0 Column 1 Offset 0x4 Length 68 Length (physical) 68
    
    filler = a                                                                   
    
    -- NOTE: The structure of each Slot is identical to that of Slot #0, so we can simply jump to slot 99:
    
    Slot 99 Offset 0x1d61 Length 75
    
    Record Type = PRIMARY_RECORD        Record Attributes =  NULL_BITMAP    Record Size = 75
    
    Memory Dump @0x0000000012A3BD61
    
    0000000000000000:   10004800 61202020 20202020 20202020 20202020  ..H.a               
    0000000000000014:   20202020 20202020 20202020 20202020 20202020                      
    0000000000000028:   20202020 20202020 20202020 20202020 20202020                      
    000000000000003C:   20202020 20202020 20202020 010000                         ...
    
    Slot 99 Column 1 Offset 0x4 Length 68 Length (physical) 68
    
    filler = a 
    
    我们可以看到最后一个插槽在7521字节之后开始,加上它的大小,我们得到了7596字节。如果我们添加插槽数组的大小(其中每个指针为2个字节),我们将得到7796个字节


    然而,我们需要得到8192字节来填充页面。少了什么

    72K的保留空间包括64K扩展数据块(8页,每个8K)加上8K IAM页面开销。在这72K中,实际上只使用IAM页和单个数据页
    sp_space_used
    以索引大小报告IAM页面,尽管从技术上讲不是索引。您可以在未记录的
    sys.dm\u db\u数据库\u页面\u分配中查看这些详细信息(仅在测试系统上使用):

    显然,该数据库的
    MIXED_PAGE_分配
    database选项设置为
    OFF
    ,因此最初会分配一个完整的64K数据块。如果该选项处于启用状态,则单个数据页将从混合扩展数据块分配,而不是从表专用的64K扩展数据块分配。在这种情况下分配的空间为16K—8K单数据页加IAM页

    尽管混合扩展数据块确实减少了小表(低于64K)的空间需求,但混合扩展数据块的开销更大,并且在高并发工作负载中可能会导致分配争用,因此在SQL 2016以后的版本中,它默认处于关闭状态。在较旧的SQL版本中,混合数据块分配在默认情况下处于打开状态,可以在服务器级别使用跟踪标志1118关闭

    您可以在
    sys.databases
    中看到混合数据块设置:

    SELECT name, is_mixed_page_allocation_on
    FROM sys.databases;
    
    要切换设置,请执行以下操作:

    ALTER DATABASE Test
        SET MIXED_PAGE_ALLOCATION ON;
    
    编辑1:

    数据页内的空间包括页本身的开销以及页内的记录。这一开销,加上用户数据所需的空间,将决定一页上可以容纳多少行以及存储给定行数所需的数据页数。请参阅Paul Randal的和文章,了解该开销的详细信息

    编辑2:

    根据您的后续评论:

    7998字节,因此下一次分配还有194个字节。 我错过了什么

    我几乎从不使用堆,但正如您在页面转储中看到的,此页面的关联PFS(页面可用空间)分配状态为100%已满。根据本书,PFS状态实际上是这些范围的3位掩码:

    • 000:空
    • 001:1-50%满
    • 010:51-80%满
    • 011:81-95%满
    • 100:96-100%满

    所以看起来,一旦堆页面满度超过96%的阈值,它就被认为是100%满的,并分配了一个新页面。请注意,这不会发生在具有聚集索引的表上,因为新行的页面首先由CI键确定,并且仅当新页面根本无法放入该页面时才分配新页面。还有一个避免堆积的原因。

    谢谢。我编辑了这个问题以包含一个后续问题,如果您也可以参考它的话,那就太好了。@HeyJude,a为我的答案添加了一个解释。好吧,我正在尝试做数学计算:6900字节的普通数据+800字节(8*100)的记录头+2(或3?)字节的空位图+96字节的页面头+200字节(2*100)插槽数组指针的数量=7998字节,因此下一次分配还有194个字节。我错过了什么?(顺便说一句,不知什么原因,
    DBCC-PAGE
    只对带有TABLERESULTS
    有效,这不是很方便,否则我会尝试更仔细地查看页面内容)。@HeyJude,你需要执行DBCC-TRACEON(3604)来查看没有TABLE_结果的DBCC-PAGE输出。谢谢,我添加了转储,也许你能告诉我我错过了什么。
    
    ALTER DATABASE Test
        SET MIXED_PAGE_ALLOCATION ON;