虽然估计直线行和表的大小是相当简单的数学运算,但我们发现猜测每个索引将占用多少空间(对于给定的表大小)很有挑战性。我们可以在哪些领域学习计算指数的更好估计和增长率?
索引叶有一个前导码,用于标识数据页(7个字节加上可变长度列的一些目录信息,如果有的话),加上键值的副本,该副本的大小与这些列的表数据的大小相同。表中每行一个。索引的较高级别要小得多,通常不到叶子的1%,除非你正在索引一个非常宽的键。
填充因子会留下一些空闲空间,以便更新和插入不会产生过多的叶拆分流量。
编辑:这个MSDN链接描述了页面级别的结构,尽管它对单个索引行的格式有点轻。本演示文稿在一定程度上介绍了磁盘日志项和数据页的物理格式。这一点更加详细,并包括索引数据结构。数字列和固定长度列的大小与方框上所示的大小相同;您必须估计varchar列的平均大小。
为了参考,可以在此处和此处找到一些关于Oracle块格式的文档。
在可能的情况下,我通常从原始表中提取1000条记录,把它们插入我自己的表中,下面的剧本我有一个样本可以玩。
好吧,这并不准确,但可以给我一个起点。
--Find out the disk size of an index:
--USE [DB NAME HERE]
go
SELECT
OBJECT_NAME(I.OBJECT_ID) AS TableName,
I.name AS IndexName,
8 * SUM(AU.used_pages) AS 'Index size (KB)',
CAST(8 * SUM(AU.used_pages) / 1024.0 AS DECIMAL(18,2)) AS 'Index size (MB)'
FROM
sys.indexes I
JOIN sys.partitions P ON P.OBJECT_ID = I.OBJECT_ID AND P.index_id = I.index_id
JOIN sys.allocation_units AU ON AU.container_id = P.partition_id
--WHERE
-- OBJECT_NAME(I.OBJECT_ID) = '<TableName>'
GROUP BY
I.OBJECT_ID,
I.name
ORDER BY
TableName
--========================================================================================
--http://msdn.microsoft.com/en-us/library/fooec9de780-68fd-4551-b70b-2d3ab3709b3e.aspx
--I believe that keeping the GROUP BY
--is the best option in this case
--because of sys.allocation_units
--can have 4 types of data inside
--as below:
--type tinyint
--Type of allocation unit.
--0 = Dropped
--1 = In-row data (all data types, except LOB data types)
--2 = Large object (LOB) data (text, ntext, image, xml, large value types, and CLR user-defined types)
--3 = Row-overflow data
--marcelo miorelli 8-NOV-2013
--========================================================================================