索引性能BigInt vs VarChar

Raj*_*ore 7 t-sql performance sql-server-2005

这是数据仓库中FACT表

它具有如下综合指数

ALTER TABLE [dbo].[Fact_Data] 
ADD  CONSTRAINT [PK_Fact_Data] 
PRIMARY KEY CLUSTERED 
(
    [Column1_VarChar_10] ASC,
    [Column2_VarChar_10] ASC,
    [Column3_Int] ASC,
    [Column4_Int] ASC,
    [Column5_VarChar_10] ASC,
    [Column6_VarChar_10] ASC,
    [Column7_DateTime] ASC,
    [Column8_DateTime] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, 
SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

在此结构中,所有varchar 10列仅具有数值.在查询和索引方面,改变这个7800万行结构来保持BIGINT而不是VARCHAR会对我有益吗?

我应该考虑的任何其他好处/缺点?

mar*_*c_s 14

你应该明确地介绍一个代理INT IDENTITY()主键!INT已经为您提供了多达20亿行 - 这还不够吗?

SQL Server上的这个主键/聚簇键的大小最多为64个字节(而不是4个,对于INT) - 这将使您的聚簇索引和所有非聚集索引膨胀得无法识别.整个集群密钥(所有8列)将包含在该表上每个非聚集索引的每个页面上 - 确实浪费了大量空间.

因此,在任何给定的索引表上,使用代理INT聚簇键的条目最多可达16倍 - 这意味着I/O减少了很多,浪费了大量的时间来读取索引页.

想象一下,尝试与该表建立外键关系......任何子表都必须将主键的所有8列作为外键列,并在每个连接中指定所有8列 - 这真是一场噩梦! !

在7800万行中,即使只将集群密钥更改为INT IDENTITY,每行最多可节省60个字节 - 仅此一项就可达到4 GB的磁盘空间(以及服务器中的RAM使用率).而这甚至没有开始计算非聚集指数的节省.......

当然,是的,我也会将VARCHAR(10)更改为INT或BIGINT - 如果它是一个数字,请将字段类型设为数字 - 确实将它留在VARCHAR(10)没有意义.但仅凭这一点并不会在速度或性能方面产生巨大的差异 - 它只是使得处理数据变得更加容易(例如在比较值等时不必总是转换为数字类型).