我有以下查询:
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)
但是, SLAName 列是唯一的,因此具有唯一的约束/索引。 我创建的索引是否过大?我还是需要它还是SQL Server将使用在唯一列 SLAName 上创建的索引?
答案 0 :(得分:2)
如果您的索引仅位于SLAName
上,那将是一个“过大杀手”,但同时您也按FK_SLA_Process
和IsActive
进行排序,因此需要需求列的查询将从中受益更多您的索引,如果只有唯一索引,则更少。
对于这样的查询:
SELECT PrimaryKey
FROM dbo.SLA
WHERE SLAName = 'SomeName'
两个索引都将产生相同的结果,您的索引将毫无意义。但是对于类似这样的查询:
SELECT PrimaryKey
FROM dbo.SLA
WHERE SLAName = 'SomeName'
AND FK_SLA_Process = 'Some Value'
或
SELECT SLATimeInSeconds
FROM dbo.SLA
WHERE SLAName = 'SomeName'
您的索引将比唯一索引更好(第二个示例是覆盖索引)。
您应该检查对该表执行哪种SELECT
并确定是否需要此表。请记住,拥有许多索引可能会加快选择速度,但会降低插入,更新和删除的速度。
答案 1 :(得分:1)
假设您有这样的表声明:
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'
它的查询计划指示索引查找,因为我们正在按索引UNIQUE NONCLUSTERED ([SLAName] ASC )
进行搜索,并且不使用WHERE
语句中的其他列:
但是,如果您向WHERE
中添加了额外的参数:
SELECT s.ID
FROM dbo.SLA s
WHERE s.SLAName = 'test'
AND s.fk_SLA = 1
AND s.IsActive = 1
执行计划会额外查找:
当索引没有必要的信息时,将发生查找。 SQL查询引擎必须从UNIQUE NONCLUSTERED
索引数据结构中找出表fk_SLA
中列IsActive
和SLA
的数据。
因此,与拥有UNIQUE NONCLUSTERED
索引一样,您的索引是过大的:
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]
答案 2 :(得分:0)
如果SLAName
列为unique
且具有unique constraint
,则任何仅返回一或0行的查询(所有查询均带有点搜索包含SLAName = 'SomeName'
条件的关键字)将使用unique index
并在基表中最多设置一个lookup
。
除非您的查询具有SLAName like 'SomeName%'
之类的范围搜索,否则无需覆盖索引,因为索引搜索+ 1查找与仅索引搜索几乎相同,也不需要浪费空间/维持另一个索引来获得如此可怜的性能提升。