如何计算其中包含列的非聚集索引的 Num_Key_Cols?
How to calculate the Num_Key_Cols for a Non-Clustered Index with included columns in it?
我正在尝试使用 MSDN website 中提供的信息来估计索引大小。
让我们考虑一个包含三列的 table "Table1"。
下面列出了这些列,
- Id int,不为空
- 标记为整数,不为空
- 提交日期日期,不为空
最初,我在 Id 列上创建了一个聚簇主键,然后计划用 "Id" 创建一个非聚簇索引作为 "index key column" 其中,"Marks" 和 "SubmitDate" 列将用作 [=索引中的 26=]"Included Columns".
根据上述计划,我试图在创建非聚集索引键之前估计它的大小。在浏览 MSDN site 时,我有很多困惑需要澄清。估计非聚集索引键大小有四个步骤,第一步,1.2和1.3解释了,如何计算Num_Key_Cols、Fixed_Key_Size、Num_Variable_Key_Cols 和 Max_Var_Key_Size。但是在1.2和1.3,我们要根据Index key的类型来计算,有没有聚簇索引key,有没有包含列;这似乎令人困惑。任何人都可以根据我提供的有关示例 table(表 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
Initially, I have created a clustered primary key on Id column and then planned to create a non-clustered index with "Id" as "index key column" where as, "Marks" and "SubmitDate" columns will be used as "Included Columns" in the index.
我不会这样做。通过使 Id
成为 table 的主键(即唯一)和集群键(只有 3 列),在 Id
上添加进一步的 NC 索引几乎没有意义 -聚集索引就足够了。
如果 table 中有大量(页面上的)列,那么可能有理由在 Id
上添加另一个 NC 索引,并在 (Marks, SubmitDate)
上包含列因为 NC 索引密度会更高。但这里显然不是这样。
对 MSDN NC 大小的一些说明 link:
- 需要在树的所有级别考虑直接索引列。
INCLUDE
列仅存在于树的叶节点中
Num_Key_Cols = Num_Key_Cols + 1
仅在 Sql 服务器添加 4 byte uniquifier 时才需要,前提是集群键不是唯一的。您已按主键聚类,因此它是唯一的,所以不是 +1。
记得还要对真实数据进行实证测量
并非所有 table 和索引都具有固定的列宽 - 许多具有可变长度的索引列,如 (N)VARCHAR
,在这种情况下,table 和索引消耗的实际存储空间高度依赖于此类字段的平均长度。
在这种情况下,我建议创建 table 并用近似数据填充它,然后使用 sp_spaceused
和 sys.dm_db_index_physical_stats
等工具测量实际数据存储,例如:
select * from sys.dm_db_index_physical_stats (DB_ID(),
OBJECT_ID(N'dbo.Table1'), NULL, NULL , 'DETAILED');
(页面大小为 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 索引一样 - 您只需将存储需求增加一倍。
顺便说一句,还请注意,通常 the clustered index key is included in all non-clustered indexes 是自动的,不需要显式添加到非聚集索引中。
我正在尝试使用 MSDN website 中提供的信息来估计索引大小。
让我们考虑一个包含三列的 table "Table1"。 下面列出了这些列,
- Id int,不为空
- 标记为整数,不为空
- 提交日期日期,不为空
最初,我在 Id 列上创建了一个聚簇主键,然后计划用 "Id" 创建一个非聚簇索引作为 "index key column" 其中,"Marks" 和 "SubmitDate" 列将用作 [=索引中的 26=]"Included Columns".
根据上述计划,我试图在创建非聚集索引键之前估计它的大小。在浏览 MSDN site 时,我有很多困惑需要澄清。估计非聚集索引键大小有四个步骤,第一步,1.2和1.3解释了,如何计算Num_Key_Cols、Fixed_Key_Size、Num_Variable_Key_Cols 和 Max_Var_Key_Size。但是在1.2和1.3,我们要根据Index key的类型来计算,有没有聚簇索引key,有没有包含列;这似乎令人困惑。任何人都可以根据我提供的有关示例 table(表 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
Initially, I have created a clustered primary key on Id column and then planned to create a non-clustered index with "Id" as "index key column" where as, "Marks" and "SubmitDate" columns will be used as "Included Columns" in the index.
我不会这样做。通过使 Id
成为 table 的主键(即唯一)和集群键(只有 3 列),在 Id
上添加进一步的 NC 索引几乎没有意义 -聚集索引就足够了。
如果 table 中有大量(页面上的)列,那么可能有理由在 Id
上添加另一个 NC 索引,并在 (Marks, SubmitDate)
上包含列因为 NC 索引密度会更高。但这里显然不是这样。
对 MSDN NC 大小的一些说明 link:
- 需要在树的所有级别考虑直接索引列。
INCLUDE
列仅存在于树的叶节点中Num_Key_Cols = Num_Key_Cols + 1
仅在 Sql 服务器添加 4 byte uniquifier 时才需要,前提是集群键不是唯一的。您已按主键聚类,因此它是唯一的,所以不是 +1。
记得还要对真实数据进行实证测量
并非所有 table 和索引都具有固定的列宽 - 许多具有可变长度的索引列,如 (N)VARCHAR
,在这种情况下,table 和索引消耗的实际存储空间高度依赖于此类字段的平均长度。
在这种情况下,我建议创建 table 并用近似数据填充它,然后使用 sp_spaceused
和 sys.dm_db_index_physical_stats
等工具测量实际数据存储,例如:
select * from sys.dm_db_index_physical_stats (DB_ID(),
OBJECT_ID(N'dbo.Table1'), NULL, NULL , 'DETAILED');
(页面大小为 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 索引一样 - 您只需将存储需求增加一倍。
顺便说一句,还请注意,通常 the clustered index key is included in all non-clustered indexes 是自动的,不需要显式添加到非聚集索引中。