Правильная индексация таблицы дает перечисленные запросы - PullRequest
1 голос
/ 31 октября 2011

У меня есть следующая таблица в SQL Server:

CREATE TABLE [dbo].[Users](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Email] [varchar](128) NOT NULL,
    [CreatedAt] [datetime] NOT NULL,
    [SourceId] [int] NOT 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]
) ON [PRIMARY]

У этой таблицы большой потенциал. Наиболее частые запросы, выполняемые в этой таблице, будут следующими:

SELECT * FROM Users WHERE Email = 'some@email.com'
SELECT * FROM Users WHERE Email = 'some@email.com' AND SourceId = some integer
SELECT * FROM Users WHERE CreatedAt BETWEEN '2011-10-01' AND '2011-10-30'
SELECT * FROM Users WHERE CreatedAt BETWEEN '2011-10-01' AND '2011-10-30' AND SourceId = some integer

В настоящее время я настроил следующие индексы:

CREATE INDEX IX_Users_Email_SourceId ON Users (Email, SourceId)
CREATE INDEX IX_Users_CreatedAt ON Users (CreatedAt)
CREATE INDEX IX_Users_SourceId ON Users (SourceId)

Достаточно ли этих индексов для перечисленных выше типов запросов? Должен ли я установить ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON в OFF, если это будет сильно запрашиваемая таблица? Я немного запутался в том, как правильно настроить индексы.

1 Ответ

1 голос
/ 31 октября 2011

Я бы проиндексировал их следующим образом:

WHERE Email = 'some@email.com'
index: Email
or Email, SourceId

WHERE Email = 'some@email.com' AND SourceId = some integer
index: SourceId, Email
or Email, SourceId

WHERE CreatedAt BETWEEN '2011-10-01' AND '2011-10-30'
index: CreatedAt
or CreatedAt, SourceId 

WHERE CreatedAt BETWEEN '2011-10-01' AND '2011-10-30' AND SourceId = some integer
index: SourceId, CreatedAt 
or CreatedAt, SourceId

Трудно быть полностью уверенным в этом, какова селективность SourceId. В зависимости от этого вы можете попытаться охватить несколько запросов одним индексом (первые два можно объединить, а два последних можно объединить). Если SourceId очень избирательно (несколько строк соответствуют каждому значению), я бы не хотел объединять индексы и добиваться максимальной производительности, используя четыре индекса.

Кроме того, вы не упоминаете, сколько INSERTS / UPDATES вы ожидаете, поэтому трудно определить, насколько излишняя нагрузка на большее / меньшее количество индексов будет проигрываться.

Кроме того, ваш SELECT * делает невозможным рекомендовать закрывающие индексы и т. Д.

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