我尝试使用MSDN website提供的信息估算索引大小。
让我们考虑一个表"表1"里面有三列。 列列在下面,
最初,我在Id列上创建了一个聚簇主键,然后计划创建一个非聚集索引,其中" Id" 为" index关键栏" 其中as," Marks" 和" SubmitDate" 列将用作"索引中包含的列" 。
根据上述计划,我在创建之前尝试估计非群集索引键大小。在浏览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键类型计算,我们是否已经有聚簇索引键,是否包含了列;这似乎令人困惑。任何人都可以根据我提供的有关示例表(表1)和我想要创建的非聚集索引键结构的信息来帮助我。
就我而言,我已经包含了列,索引键列已经是主键,并且所有列都不是空字段。如何计算它的索引大小?
提前致谢。
答案 0 :(得分:2)
最初,我在Id列上创建了一个聚簇主键,然后计划使用" Id"创建一个非聚集索引。 as"索引键列" as," Marks"和" SubmitDate"列将用作"包含的列"在索引中。
我不会这样做。通过使Id
主键(即唯一)和表的聚类键(只有3列),在Id
上添加另一个NC索引几乎没有意义 - 聚簇索引就足够了。
如果表格中有大量(页面上)列,那么可能有理由在Id
上添加另一个NC索引,并在(Marks, SubmitDate)
上添加列,因为NC索引密度会更高。但这显然不是这种情况。
MSDN NC大小调整链接的一些说明:
INCLUDE
列仅存在于树的叶节点中Num_Key_Cols = Num_Key_Cols + 1
。您已按主键群集,因此其唯一,因此不是+1。请记住也要对实际数据进行经验测量
并非所有表和索引都具有固定的列宽 - 许多表具有可变长度索引列,如(N)VARCHAR
,在这种情况下,表和索引所消耗的实际存储高度依赖于此类字段的平均长度。
在这种情况下,我建议创建表格并使用近似数据填充表格,然后使用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自动,并且不需要显式添加到非聚集索引。
答案 1 :(得分:0)
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