是否为表中的每个外键隐式创建了非聚集索引?

Posted

技术标签:

【中文标题】是否为表中的每个外键隐式创建了非聚集索引?【英文标题】:Is a non-clustered index implicitly created for each foreign key in a table? 【发布时间】:2019-02-23 09:07:09 【问题描述】:

如果我有这样的表:

CREATE TABLE MyTable
(
    Id INT PRIMARY KEY IDENTITY(1, 1), 
    FooId INT NOT NULL FOREIGN KEY REFERENCES Foo(Id),
    Data NVARCHAR(10) NOT NULL
);

可以进行以下观察:

    将在主键列Id上创建聚集索引在表MyTable

    此外,可以推断,将在表 Foo 上为其名为 Id 的主键创建一个聚集索引。

问题:

是否还会为表 MyTable 上的外键 Foo.Id创建一个索引

换句话说,是为依赖表上的每个外键隐式创建的非聚集索引

换句话说,在此架构中创建的索引总数是否为 2,如下所示:

    MyTable 上的主键 Id 的聚集索引。 主键 Id 对表 Foo 的聚集索引。

或者会不会有以下3个指标:

    MyTable 上的主键 Id 的聚集索引。 在表Foo 上的主键Id 上的聚集索引。 表MyTable 上的外键Foo(Id) 的非聚集索引。

我的问题与 Microsoft SQL Server 2014 有关。

【问题讨论】:

不在 SQL Server(或大多数数据库)中。这样的索引是在 mysql 中创建的。 【参考方案1】:

不,它不是自动创建的。手动创建它是一个好习惯:

The Benefits of Indexing Foreign Keys

与主键约束不同,当为表定义外键约束时,SQL Server 默认不会创建索引。 但是,开发人员和数据库管理员手动添加它们的情况并不少见

CREATE TABLE MyTable(
  Id int PRIMARY KEY IDENTITY(1, 1), 
  FooId int NOT NULL FOREIGN KEY REFERENCES Foo(Id),
  Data nvarchar(10) NOT NULL,
);

exec sp_helpIndex 'MyTable'

index_name  index_description   index_keys
PK__MyTable__3214EC0742A69968   clustered, unique, primary key located on PRIMARY Id

显式索引创建:

CREATE TABLE MyTable (
  Id int PRIMARY KEY IDENTITY(1, 1), 
  FooId int NOT NULL FOREIGN KEY REFERENCES Foo(Id),
  Data nvarchar(10) NOT NULL,
  INDEX FK_FooId nonclustered(FooId)  -- inline syntax
); 

exec sp_helpIndex 'MyTable'

index_name  index_description   index_keys
FK_FooId    nonclustered located on PRIMARY     FooId
PK__MyTable__3214EC0779B032FB   clustered, unique, primary key located on PRIMARY Id

db<>fiddle demo

【讨论】:

这个答案:完美。清晰、简洁、正确。 (并且 TIL 大写对存储过程无关紧要 - Sp_HeLpInDeX,甚至!)

以上是关于是否为表中的每个外键隐式创建了非聚集索引?的主要内容,如果未能解决你的问题,请参考以下文章

选择啥列来创建聚集索引

聚集索引和取消外键,外键影响在大并发下的性能.删除外键

数据库中的聚集索引非聚集索引优化索引

5级阶梯SQL Server索引

数据库中的聚集索引非聚集索引优化索引

MySQL中怎样创建聚集索引和非聚集索引,求创建这两种索引的SQL语句。谢谢