sql server中聚集索引不必强制唯一,但primary key默认创建唯一聚集索引;手动创建时可不加unique,不过重复键值会触发sql server自动添加隐藏uniquifier列,影响性能与空间,故实践强烈建议设为唯一。

SQL Server里聚集索引必须是唯一索引吗
不是必须,但PRIMARY KEY默认会建唯一聚集索引;如果你手动创建聚集索引,可以不加UNIQUE,只要不违反聚集索引的物理排序要求即可。不过实践中强烈建议设为唯一——否则重复键值会导致SQL Server自动添加隐藏的uniquifier列,既浪费空间又影响性能。
Navicat for SQL Server中怎么选“聚集索引”类型
在“设计表”→“索引”页点“新增”后,关键一步是:下拉选择Index Type时,必须选Clustered(不是Non-Clustered)。注意:Clustered选项只在SQL Server连接下可见;MySQL/PostgreSQL连接里这个下拉菜单压根不会出现该选项,因为它们不支持用户手动指定聚集行为(InnoDB主键即聚簇,MyISAM无聚簇概念)。
常见误操作:
- 误把
Primary Key和Clustered Index当成一回事:主键≠聚集索引,你完全可以建一个NONCLUSTERED PRIMARY KEY,再另建CLUSTERED索引在别的列上 - 勾选了
Unique但没注意Clustered下拉框仍停留在Non-Clustered,结果建出来的是唯一非聚集索引
建聚集索引前必须检查的三件事
SQL Server不允许一张表同时存在多个聚集索引,也不允许对已有聚集索引的表直接新建第二个——Navicat点确定时会报错:Cannot create more than one clustered index on table 'xxx'。所以动手前务必确认:
- 用
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('your_table') AND type = 1查当前是否有聚集索引(type = 1) - 如果表是堆(heap),且已有多个非聚集索引,建聚集索引会触发所有非聚集索引重建——大表可能卡住几十分钟,建议在低峰期操作
-
varchar列如果已存有超长数据(触发ROW_OVERFLOW_DATA),且你试图把它作为聚集索引第一列,SQL Server会拒绝:错误信息类似The index '<name>' could not be created or rebuilt because the column '<col>' contains data that exceeds the maximum length allowed for an index key</name>
为什么Navicat建完聚集索引,执行计划还是没走它
执行计划里key为空、type是ALL,不代表Navicat没建成功,大概率是查询写法或字段顺序不匹配。重点排查:
- WHERE条件是否满足最左前缀?比如索引是
idx_created_at_status(created_at, status),但查询是WHERE status = 1——跳过首列,聚集索引失效 - 是否对索引列用了函数?
WHERE YEAR(created_at) = 2025会让整个聚集索引失效,得改成created_at >= '2025-01-01' AND created_at - 参数类型是否隐式转换?
created_at是datetime,但传入字符串'2025-01-01',SQL Server可能放弃索引做全表扫描
真正容易被忽略的是:聚集索引一旦建在非主键列上,而你后续又加了PRIMARY KEY约束,默认会悄悄把聚集索引转移到主键列——原聚集索引自动转成非聚集,这个过程Navicat界面不会提醒,只能靠sys.indexes查。











