Нужен ли этот индекс для таблицы? - PullRequest
0 голосов
/ 26 июня 2019

У меня есть таблица с 5 индексами в SQL-сервере. Мне известно о том, что индексы влияют на вставки, поэтому я хотел бы свести их к минимуму. Мне определенно нужны первые четыре индекса (как видно из примера ниже). Тем не менее, я совершенно уверен, что последний индекс (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 ]

2 голосов
/ 26 июня 2019

Да, индекс IX_MyTable_TimeSubmitted будет полезен для процесса очистки, который вы описали.Поскольку очистка основана только на столбце TimeSubmitted и ни один из других индексов не начинается с этого, лучшее, что может сделать SQL Server, - это использовать их при сканировании индекса.

Как и при любом индексировании,Есть компромиссы между производительностью чтения и обновления.Вы должны измерить производительность чтения, вставки и очистки с дополнительным индексом и без него, чтобы увидеть, что обеспечивает лучшее время отклика для каждой ситуации.Пакетные процессы, такие как очистка, выполняемая в одночасье, могут быть не такими чувствительными ко времени, как вставка или чтение в вашем конкретном сценарии.

1 голос
/ 26 июня 2019

Если вы беспокоитесь о производительности, вам следует использовать другой подход - разбиение.Разумное место для разбивки на разделы - документация .

. Секционированная таблица хранит каждый раздел в отдельном наборе файлов.Они вообще невидимы для пользователей базы данных.Однако, если вы хотите удалить старые данные, вы можете просто удалить раздел.

Это не только устраняет необходимость в индексе.Это также устраняет необходимость в delete.Кроме того, удаление раздела гораздо эффективнее, чем удаление, поскольку журналов намного меньше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...