给定一些带有主键的表,例如:
CREATE TABLE Customers (
CustomerID int NOT NULL PRIMARY KEY,
FirstName nvarchar(50),
LastName nvarchar(50),
Address nvarchar(200),
Email nvarchar(260)
--...
)
我们在上有一个唯一的主键CustomerID
。
传统上,我可能需要一些额外的覆盖索引。例如,通过CustomerID
或快速查找用户Email
:
CREATE INDEX IX_Customers_CustomerIDEmail ON Customers
(
CustomerID,
Email
)
这些都是我数十年来创建的索引。
不一定要唯一,但实际上是
索引本身的存在是为了避免进行表扫描。它是覆盖索引,以帮助提高性能(该索引不存在作为强制执行唯一性的约束)。
今天,我想起了一些信息-SQL Server可以使用以下事实:
- 列具有外键约束
- 列具有唯一索引
- 约束是可信的
为了帮助它优化查询执行。实际上,根据《SQL Server索引设计指南》:
如果数据是唯一的并且您要强制执行唯一性,那么在相同的列组合上创建唯一索引而不是非唯一索引将为查询优化器提供附加信息,从而可以产生更有效的执行计划。在这种情况下,建议创建唯一索引(最好通过创建UNIQUE约束)。
鉴于我的多列索引包含主键,因此该复合索引实际上将是唯一的。这不是我特别需要SQL Server在每次插入或更新期间强制执行的约束;但是事实是该非聚集索引是唯一的。
将这个事实上的唯一索引标记为实际上唯一有什么好处吗?
在客户上创建唯一索引IX_Customers_CustomerIDEmail ( 客户ID, 电子邮件 )
在我看来,SQL Server 可能足够聪明,可以意识到我的索引已经具有唯一性,因为它包含主键。
- 但是也许它不知道,如果我将索引声明为唯一的话,对于优化器来说是有好处的。
- 除非现在可能会导致插入和更新过程中的速度变慢,否则它必须执行唯一性检查-以前从未需要这样做。
- 除非它知道索引保证已经是唯一的,否则因为它包含主键。
对于复合索引包含主键时该怎么办,我找不到Microsoft的任何指导。
唯一索引的优点包括:
- 确保已定义列的数据完整性。
- 提供了有助于查询优化器的其他信息。
如果复合索引已经包含主键,是否应该将其标记为唯一?还是SQL Server可以自己解决这个问题?