SQL Server-是否正在创建具有唯一约束的索引作为必需的列之一?

SQL Server-是否正在创建具有唯一约束的索引作为必需的列之一?,sql,sql-server,indexing,Sql,Sql Server,Indexing,我有以下疑问: SELECT PrimaryKey FROM dbo.SLA WHERE SLAName = @input AND FK_SLA_Process = @input2 AND IsActive = 1 这是我对这个SLA表的索引 CREATE INDEX IX_SLA_SLAName_FK_SLA_Process_IsActive ON dbo.SLA (SLAName, FK_SLA_Process, IsActive) INCLUDE (SLATimeInSeconds)

我有以下疑问:

SELECT PrimaryKey
FROM dbo.SLA
WHERE SLAName = @input
AND FK_SLA_Process = @input2
AND IsActive = 1
这是我对这个SLA表的索引

CREATE INDEX IX_SLA_SLAName_FK_SLA_Process_IsActive ON dbo.SLA (SLAName, FK_SLA_Process, IsActive) INCLUDE (SLATimeInSeconds)
但是,slame列是唯一的,因此它具有唯一的约束/索引。 我创建的索引是不是太过分了?我是否仍然需要它,或者SQL Server是否会使用在唯一列SLAName上创建的索引?

如果您的索引只在
SLAName
上,这将是一种“过激”行为,但您也可以通过
FK_SLA_过程
IsActive
进行排序,因此需要列的查询将更多地受益于您的索引,而如果只有唯一的索引,则受益更少

对于这样的查询:

SELECT PrimaryKey
FROM dbo.SLA
WHERE SLAName = 'SomeName'
这两个索引将产生相同的结果,你的索引将没有意义。但对于以下问题:

SELECT PrimaryKey
FROM dbo.SLA
WHERE SLAName = 'SomeName'
AND FK_SLA_Process = 'Some Value'

您的索引将优于唯一索引(第二个示例是覆盖索引)


您应该检查对该表执行的
选择
类型,并决定是否需要该类型。请记住,有许多索引可能会加快选择,但会减慢插入、更新和删除的速度。

假设您有这样的表声明:

CREATE TABLE SLA
(
   ID  INT PRIMARY KEY,
   SLAName VARCHAR(50) NOT NULL UNIQUE,
   fk_SLA INT,
   IsActive TINYINT
)
在引擎盖下,我们有两个索引:

CREATE TABLE [dbo].[SLA](
    [ID] [int] NOT NULL,
    [SLAName] [varchar](50) NOT NULL,
    [fk_SLA] [int] NULL,
    [IsActive] [tinyint] NULL,
PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
UNIQUE NONCLUSTERED 
(
    [SLAName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
    ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
因此,此查询将有一个索引搜索,并有一个最佳计划:

SELECT s.ID 
FROM dbo.SLA s 
WHERE s.SLAName = 'test'
它的查询计划指示索引查找,因为我们是按索引
唯一的非聚集([SLAName]ASC)
进行搜索,并且不使用
中的其他列,其中
语句:

但如果在
中添加额外参数,其中

SELECT s.ID 
FROM dbo.SLA s 
WHERE s.SLAName = 'test'
AND s.fk_SLA = 1
AND s.IsActive = 1
执行计划将有额外的查找:

当索引没有必要的信息时,就会进行查找。SQL查询引擎必须从
唯一的非聚集
索引数据结构中找出表
SLA
fk_SLA
IsActive
列的数据

因此,您的索引是多余的,因为您有
唯一的非聚集索引
索引:

UNIQUE NONCLUSTERED 
(
    [SLAName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

如果
SLAName
列是
unique
并且它有一个
unique约束
,任何只返回一行或0行的查询(所有带有
SLAName='SomeName'
条件的点搜索的查询)将使用
唯一索引
并生成(最大值)一个
查找
在基表中

除非您的查询有一个范围搜索
slame像'SomeName%'
否则没有必要覆盖索引,因为索引搜索+1查找几乎与仅索引搜索相同,并且没有必要为了如此糟糕的性能增益而浪费空间/维护另一个索引

您应该阅读有关“覆盖索引”的内容,看看这对提高查询性能何时有用。如果没有更多的信息,就无法确定它是否会对您的数据库有所帮助。您可以从阅读本文开始:
UNIQUE NONCLUSTERED 
(
    [SLAName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]