该表上的索引是否必要?

时间:2019-06-26 15:23:59

标签: sql sql-server tsql

我在SQL Server中有一个包含5个索引的表。我知道索引会影响插入的事实,因此我想将其保持在最低限度。我肯定需要前四个索引(如以下示例所示)。 但是,我非常确定最后一个索引(TimeSubmitted)是否绝对必要-请注意,已经有CliendId + TimeSubmitted索引。 这样做的唯一原因是使从表中清除过期行更加有效-至少这就是我的意图。清除作业将计划每天运行一次-最有可能在晚上进行。

在任何给定时间,表中可能有数十万条记录。

用于清除表的存储过程:

CREATE PROCEDURE uspPurgeMyTable
(
    @ExpiryDate datetime
)
AS
BEGIN
    DELETE FROM MyTable
    WHERE TimeSubmitted < @ExpiryDate;    
END

表(忽略不相关的列):

CREATE TABLE MyTable (
    [ClientId] [char](36) NOT NULL,
    [UserName] [nvarchar](256) NOT NULL,
    [TimeSubmitted] [datetime] NOT NULL,
    [ProviderId] [uniqueidentifier] NULL,
    [RegionId] [int] NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_MyTable_ClientArea] ON [dbo].[MyTable]
(
    [ClientId] ASC,
    [RegionId] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_MyTable_ClientPrinter] ON [dbo].[MyTable]
(
    [ClientId] ASC,
    [ProviderId] DESC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_MyTable_ClientTime] ON [dbo].[MyTable]
(
    [ClientId] ASC,
    [TimeSubmitted] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_MyTable_ClientUser] ON [dbo].[MyTable]
(
    [ClientId] ASC,
    [UserName] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
GO

CREATE NONCLUSTERED INDEX [IX_MyTable_TimeSubmitted] ON [dbo].[MyTable]
(
    [TimeSubmitted] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]

2 个答案:

答案 0 :(得分:2)

是的,IX_MyTable_TimeSubmitted索引将对您描述的清除过程很有帮助。由于清除仅基于TimeSubmitted列,而其他索引都不以此开头,因此最好的SQL Server能够做到的是在索引扫描中使用它们。

与任何索引编制一样,在读取和更新性能之间需要权衡。在使用和不使用附加索引的情况下,您应该测量读取,插入和清除性能,以了解哪种情况可以为每种情况提供最佳响应时间。整夜运行的批处理(例如清除)可能不像在特定情况下插入或读取那样对时间敏感。

答案 1 :(得分:1)

如果您担心性能,则应采用其他方法进行分区。 documentation是学习分区的一个合理位置。

分区表将每个分区存储在一组单独的文件中。通常,这些对于数据库用户是不可见的。但是,如果要删除旧数据,则可以删除分区。

这不仅消除了对索引的需要。它还消除了对delete的需要。而且,删除分区比删除要有效得多,因为日志记录要少得多。