索引的几个凝问
大家对主键这个词都不陌生吧?在SQL Server中肯定也都用过,那么你是否真的理解透彻了呢?有没有和唯一性约束、聚集索引、唯一性索引等概念混淆起来?好,让我们从几个典型的问题入手来好好辨一辨吧:
1. 假设一张表上已经存在一个唯一性的聚集索引,是否还有必要在该表上创建一个主键约束呢?
2. 如果需要主键约束,是否要先删除之前创建过的唯一性聚集索引,再新建主键约束呢?
3. 针对相同的字段,通过主键约束自动生成的唯一性聚集索引的性能会比手工直接创建的唯一性聚集索引更好吗?
仔细思考几分钟,再来看答案哦……
1. 这个问题的答案已经是老生常谈了:尽管为表建主键可以称为一种最佳实践,但是如果你并不关心主键所带来的好处的话,建议还是不要盲目地创建。主键的好处或者说作用究竟是什么呢?首先,需要明确一点,主键是一种约束,而约束实际上是一种逻辑的概念。主键的存在一般起到如下两个作用:
(a) 实体完整性。换句话说,要保证表内数据的唯一性,避免重复。
(b) 引用完整性。典型地是应用于“主键—外键”对上。
既然主键是一种逻辑的概念,它本身是不会造成任何性能上的影响的。但是我们为何不能盲目创建呢?这是因为在SQL Server中,新增主键的操作会伴随一个唯一性索引的生成(默认情况下是聚集索引)来保证实体完整性。因此,新增主键可以说会间接地影响性能,这是由索引造成的。回到这个问题上,从性能的角度考虑,如果表上当前存在的唯一性聚集索引已经是较优的选择(满足了重要查询的需求),就没有必要再通过新建主键来替换它,性能不会因为多了一个主键的约束而有所提升。
2. 这个问题在上一个当中已经有所涉及。这里有一个重要的知识点:同一张表上最多只能有一个聚集索引。因此,我们有两种选择:
(a) 保留原来的聚集索引,新建一个带有非聚集索引的主键(需要显式指定NONCLUSTERED)。
(b) 删除原来的聚集索引,然后再新建一个带有聚集索引的主键(默认即可)。
3. 从性能的角度考虑,回答是否定的。所以在动手以前,应该仔细斟酌好主键所带的索引究竟需要聚集的还是非聚集的,因为聚集索引是十分宝贵的,需要做好充分地评估。如果任由主键默认聚集索引的话,可能并不一定是聚集索引的最佳选择,今后可能还需要重新调整聚集索引和非聚集索引的选择。
总而言之,主键是一个逻辑上的概念,主要提供数据在实体完整性和引用完整性上的保障。性能因素是由主键自带的索引造成的,谨记在创建主键时要想好主键字段究竟选择聚集的还是非聚集的,如果不关心主键所带来的好处的话,还是选择不加为好。希望本文能够帮助你更好地理解主键存在的意义及其间接存在的性能问题。