Sql 如何计算包含列的非聚集索引的Num_Key_Cols?

Sql 如何计算包含列的非聚集索引的Num_Key_Cols?,sql,sql-server,sql-server-2008,indexing,non-clustered-index,Sql,Sql Server,Sql Server 2008,Indexing,Non Clustered Index,我正试图使用网站上提供的信息来估计索引大小 让我们考虑一个表“表1”,里面有三列。 下面列出了这些列 Id int,不为null 标记int,而不是null 提交日期,不为空 最初,我在Id列上创建了一个聚集主键,然后计划创建一个非聚集索引,其中,“Id”作为“index key column”,其中,“Marks”和“SubmitDate”列将用作索引中的“Included columns” 基于上述计划,我试图在创建非聚集索引键之前估计它的大小。在阅读过程中,我有很多困惑需要澄清。估计非聚集

我正试图使用网站上提供的信息来估计索引大小

让我们考虑一个表“表1”,里面有三列。 下面列出了这些列

  • Id int,不为null
  • 标记int,而不是null
  • 提交日期,不为空
  • 最初,我在Id列上创建了一个聚集主键,然后计划创建一个非聚集索引,其中,“Id”作为“index key column”,其中,“Marks”“SubmitDate”列将用作索引中的“Included columns”

    基于上述计划,我试图在创建非聚集索引键之前估计它的大小。在阅读过程中,我有很多困惑需要澄清。估计非聚集索引键大小有四个步骤,在第一步,1.2和1.3解释了如何计算Num\u key\Cols、Fixed\u key\u size、Num\u Variable\u key\Cols和Max\u Var\u key\u size。但是在1.2和1.3中,我们应该根据索引键类型进行计算,是否已经有聚集索引键,是否包含列;这似乎令人困惑。根据我提供的关于示例表(表1)和我要创建的非聚集索引键结构的信息,有人能帮我吗

    在我的例子中,我包含了列,索引键列已经是主键,所有列都不是空字段。如何计算它的索引大小

    提前谢谢

    SELECT
    OBJECT_NAME(i.OBJECT_ID) AS TableName,
    i.name AS IndexName,
    i.index_id AS IndexID,
    8 * SUM(a.used_pages) AS 'Indexsize(KB)'
    FROM sys.indexes AS i
    JOIN sys.partitions AS p ON p.OBJECT_ID = i.OBJECT_ID AND p.index_id = i.index_id
    JOIN sys.allocation_units AS a ON a.container_id = p.partition_id
    GROUP BY i.OBJECT_ID,i.index_id,i.name
    ORDER BY OBJECT_NAME(i.OBJECT_ID),i.index_id
    
    最初,我在Id列上创建了一个聚集主键,然后计划创建一个非聚集索引,其中“Id”作为“索引键列”,其中“Marks”和“SubmitDate”列将用作索引中的“Included列”

    我不会这么做的。通过使
    Id
    同时成为表的主键(即唯一键)和聚类键(只有3列),在
    Id
    上添加进一步的NC索引几乎没有意义-聚类索引就足够了

    如果表中有大量(第页)列,则可能有理由在
    Id
    上添加另一个NC索引,并在
    (Marks,SubmitDate)
    上包含列,因为NC索引密度会更高。但这里显然不是这样

    对MSDN NC尺寸调整链接的一些澄清:

    • 树的所有级别都需要考虑直接索引列
    • INCLUDE
      列仅存在于树的叶节点中
    • Num\u Key\u Cols=Num\u Key\u Cols+1
      仅在Sql Server添加群集密钥时才需要。您已按主键聚集,因此它是唯一的,因此不是+1
    记住还要对真实数据进行经验测量

    并非所有表和索引都具有固定列宽-许多表和索引具有可变长度的索引列,如
    (N)VARCHAR
    ,在这种情况下,表和索引消耗的实际存储高度依赖于此类字段的平均长度

    在这种情况下,我建议创建表格并用近似数据填充,然后使用
    sp_spaceused
    等工具测量实际数据存储,例如:

    (页面大小为8192)

    编辑

    举个例子,如果您已经准备好了:

    CREATE TABLE Table1
    (
        Id INT IDENTITY(1,1),
        Marks INT NOT NULL,
        SubmitDate DATE NOT NULL
    );
    
    ALTER TABLE Table1 ADD CONSTRAINT PK_Table1 PRIMARY KEY CLUSTERED (Id);
    
    那么,这样做也没有意义:

    CREATE NONCLUSTERED INDEX IX_Table1 on Table1(Id) INCLUDE (Marks, SubmitDate)
    
    由于聚集索引在
    ID
    上的搜索/扫描性能与NC索引相同,因此只需将存储需求增加一倍


    另请注意,通常情况下,这是自动的,不需要显式地添加到非聚集索引。

    在我的例子中,我使用了主键(聚集键列)作为非聚集索引的索引键列。那么,当聚集索引键直接用作非聚集索引中的索引键列时,数据行定位器是如何工作的呢?我添加了一个示例-希望这能澄清问题?感谢您的帮助。我已经被你的回答澄清了。最后,我对它有另一个疑问。在“非聚集索引大小的估计”的MSDN文档中,在步骤1.4中,我必须计算“索引空值位图”,并且为了计算它,索引空值位图=2+((索引行中的列数+7)/8)。那么,此时“索引行中的列数”是多少?
    CREATE NONCLUSTERED INDEX IX_Table1 on Table1(Id) INCLUDE (Marks, SubmitDate)