聚簇和非聚簇索引性能

irr*_*iss 9 sql-server performance clustered-index

我在随机uniqueidentifier列上有一个巨大的表(大约1000万行)和聚簇PK.我对此表执行的大多数操作是在没有具有相同pk的行时插入新行.(为了提高它的性能,我使用IGNORE_DUP_KEY = ON选项)

我的问题是

我可以在这张桌子上完全摆脱聚集索引吗?我的意思是当我在一个带有聚簇索引的表中插入一行时,它应该重新排列数据.可能最好删除聚簇索引并在该列上创建非聚簇索引以避免数据重新排列?

我不能在实时数据库上做一个实验,因为如果性能下降,那将是一个令人头痛的问题.在测试数据库中,我只能在聚集索引和'表插入'的情况下看到'聚簇索引插入100%',在非聚集索引的情况下,在非聚簇索引中搜索一些操作.

提前致谢

mar*_*c_s 12

GUID似乎是您主键的自然选择 - 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY.我强烈建议不要使用GUID列作为群集密钥,默认情况下SQL Server会执行此操作,除非您明确告知不要这样做.

你真的需要分开两个问题:

1)主键是一个逻辑结构 - 一个候选键,它唯一且可靠地标识表中的每一行.这可以是任何东西,真的 - 一个INT,一个GUID,一个字符串 - 选择对你的场景最有意义的东西.

2)聚类键(在表上定义"聚簇索引"的一列或多列) - 这是一个与物理存储相关的东西,在这里,一个小的,稳定的,不断增加的数据类型是你最好的选择 - INT或者BIGINT作为您的默认选项.

默认情况下,SQL Server表上的主键也用作群集键 - 但这不一定是这样!我个人看到在将先前基于GUID的主/群集密钥分解为两个单独的密钥时的性能大幅提升 - 主要(逻辑)密钥GUID和单独INT IDENTITY(1,1)列上的群集(排序)密钥.

正如Kimberly Tripp--索引女王 - 和其他人已多次声明 - GUID因为聚类键不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片以及通常不良的性能.

是的,我知道 - newsequentialid()在SQL Server 2005及更高版本中 - 但即使这样也不是真正的,完全顺序的,因此也会遇到与GUID相同的问题 - 只是不那么突出.

然后还有另一个需要考虑的问题:表格上的聚类键也会添加到表格中每个非聚集索引的每个条目上 - 因此,您确实希望确保它尽可能小.通常,对于绝大多数表来说,具有2亿行的INT应该足够了 - 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆字节的存储空间.

快速计算 - 使用INT与GUID作为主要和群集密钥:

  • 基表有1'000'000行(3.8 MB对15.26 MB)
  • 6个非聚簇索引(22.89 MB对91.55 MB)

总计:25 MB对106 MB - 这只是在一张桌子上!

还有一些值得思考的东西 - 金伯利·特里普的优秀作品 - 阅读,再读一遍,消化它!这是SQL Server索引福音,真的.正如她在"Clustered Index Debate contiues"中所展示的那样,拥有一个好的聚类键(相对于没有或坏的)确实加速了几乎所有的数据库操作!这是一个好主意 - 但它必须是一个很好的集群密钥....