在Navicat中创建SQL Server非聚集索引,必须手动选择“索引类型”为Non-Clustered而非依赖默认;INCLUDE列需在“选项”页签中单独添加;删除聚集索引会使表退化为堆并强制重建所有非聚集索引。
在 navicat 中可视化创建 sql server 的非聚集索引,关键不是“勾选某个开关”,而是**主动选择索引类型为 non-clustered,并确保不误选成 clustered**。默认新建索引就是非聚集,但很多人因忽略下拉框选项,或误以为主键=聚集索引,结果建出不符合预期的索引。
新建索引时必须手动选 Non-Clustered 类型
Navicat 的「设计表 → 索引」界面中,没有“非聚集”复选框,只有「索引类型」下拉菜单。它的可选项是:Clustered、Non-Clustered、Spatial、XML。新建索引时默认值是 Non-Clustered,但这个默认值容易被忽略——尤其当你复制已有索引配置、或快速点击保存时,可能根本没看这一栏。
常见错误现象:
- 建完索引后执行计划里仍出现
Key Lookup,查了半天发现索引其实是Clustered(物理重排了表),但业务只需要逻辑查找加速 - 用
sp_helpindex查表索引,发现类型是clustered,而你本意是加个轻量级的Non-Clustered
实操建议:
- 每次新建索引,务必把光标点进「索引类型」下拉框,确认当前值是
Non-Clustered - 如果要建唯一非聚集索引,勾选「唯一」即可;但注意:
UNIQUE NONCLUSTERED和NONCLUSTERED在 DDL 上是两个不同约束,前者会拒绝重复值插入 - 不要依赖“主键图标”自动建索引——点字段旁钥匙图标建的是主键约束,是否聚集取决于表当前是否有其他
Clustered索引
INCLUDE 列必须在「选项」页签里填,不在主字段列表
非聚集索引要真正覆盖查询(避免 Key Lookup),常需把 SELECT 中的非键列放进 INCLUDE。但 Navicat 把它藏在二级页签里:主字段列表只管 KEY 列(即索引键),INCLUDE 列得切到「选项」页签手动添加。
常见错误现象:
- 明明建了非聚集索引,执行计划却显示「实际执行了 Bookmark Lookup」或「SQL Server 仍去聚簇索引/堆上回取数据」
- 用
SELECT * FROM sys.index_columns WHERE object_id = OBJECT_ID('xxx')查,发现is_included_column = 0,说明没生效
实操建议:
- 建非聚集索引前,先想清楚查询语句的
SELECT和WHERE字段;WHERE字段放主索引列,SELECT中的额外字段尽量放INCLUDE - 切到「选项」页签后,在「包含列」输入框里逐个添加字段名,多个用英文逗号分隔,如:
status, created_time -
INCLUDE列不能参与索引排序或过滤,也不受UNIQUE约束影响,但它能显著减少 I/O
删错聚集索引会导致表退化为堆,连带重写所有非聚集索引
如果你在 Navicat 图形界面里删掉一个 Clustered 索引(比如误删了主键上的聚集索引),SQL Server 会把表变成堆(heap)。此时所有已有的 Non-Clustered 索引里的行指针(Row ID)全部失效,SQL Server 必须重建它们——大表可能卡住数分钟甚至更久,且期间阻塞写操作。
实操建议:
- 删索引前,先用
SELECT name, type_desc FROM sys.indexes WHERE object_id = OBJECT_ID('your_table')确认目标索引类型 - 生产环境删
Clustered索引前,务必评估表大小和业务窗口;小表可直接删,大表建议改用DROP_EXISTING = ON在线替换 - 如果只是想把主键从聚集改成非聚集,不要删原主键,而是用 T-SQL 显式重建:
ALTER TABLE t ADD CONSTRAINT PK_t_id PRIMARY KEY NONCLUSTERED (id)
最易被忽略的一点:Navicat 界面里显示的索引名(比如 PK_user_id 或 IX_user_status)完全不反映它是聚集还是非聚集——唯一可靠依据是「索引类型」列的值。别凭名字猜,一定要看那一栏。


















