根据相同列的不同条件创建多个筛选索引是否有意义?例如,假设如下:
CREATE TABLE [dbo].[Skills](
[UserId] INT NOT NULL PRIMARY KEY,
[SkillTitle] NVARCHAR(50) NOT NULL,
[SkillLevel] INT NOT NULL CHECK ([SkillLevel] BETWEEN 0 AND 10)
)
GO
CREATE INDEX [IX_Skill_Low] ON [dbo].[Skill] (SkillTitle,SkillLevel) WHERE SkillLevel BETWEEN 3 AND 0
GO
CREATE INDEX [IX_Skill_Moderate] ON [dbo].[Skill] (SkillTitle,SkillLevel) WHERE SkillLevel BETWEEN 5 AND 3
GO
CREATE INDEX [IX_Skill_Good] ON [dbo].[Skill] (SkillTitle,SkillLevel) WHERE SkillLevel BETWEEN 7 AND 5
GO
CREATE INDEX [IX_Skill_High] ON [dbo].[Skill] (SkillTitle,SkillLevel) WHERE SkillLevel > 7
或者创建一个非过滤索引会更好吗?
如果进行以下查询SELECT * FROM Skills WHERE SkillLevel BETWEEN 7 AND 1
会发生什么?
答案 0 :(得分:2)
除非每个技能等级变化都有数百万条记录。
即,
在5和3之间
在5和7之间
我不建议这样做,我建议创建一个单独的过滤索引,如下所示
skilllevel between 1 and 10
如果进行以下查询会发生什么SELECT * FROM Skills WHERE SkillLevel BETWEEN 7 AND 1?
如果你的select *
包含许多列,而不是索引中没有指定的列,则sql可能
我会创建一个以下覆盖索引,但这取决于您的数据
create index nci_test on table(skilllevel)
include(SkillTitle)
我做了一些测试以了解更多,你可以在下面找到测试脚本
CREATE TABLE [dbo].[Skills](
[UserId] INT NOT NULL identity(1,1) PRIMARY KEY,
[SkillTitle] NVARCHAR(50) NOT NULL,
[SkillLevel] INT NOT NULL CHECK ([SkillLevel] BETWEEN 0 AND 10)
)
GO
insert into dbo.Skills
(SkillTitle,SkillLevel)
select cast(NEWID() as varchar(50)),
case when rand()*10<0 then 1 else rand()*10 end
go 100000
现在让我们运行一些查询
create index nci_1and5 on dbo.skills(skilllevel)
include(skilltitle)
where skilllevel >= 1 and skilllevel <=5
create index nci_5and10 on dbo.skills(skilllevel)
include(skilltitle)
where skilllevel >5 and skilllevel <=10
select * from skills where skilllevel
between 1 and 4--uses 1 to 5 index
select * from skills where skilllevel
between 6 and 10--uses 6 to 10 index
select * from skills where skilllevel
between 1 and 7--uses scan
然而,即使你在技能水平之间有数百万行,我也不推荐这些指数。我会建议分配