Поиск индекса и сканирование таблицы занимает одно и то же время - PullRequest
0 голосов
/ 24 октября 2018

У меня есть таблица со структурой, подобной этой:

CREATE TABLE [dbo].[User]
(
    [Id] [INT] IDENTITY(1,1) NOT NULL,
    [CountryCode] [NVARCHAR](2) NOT NULL DEFAULT (N'GB'),
    [CreationDate] [DATETIME2](7) NOT NULL,
    [Email] [NVARCHAR](256) NULL,
    [EmailConfirmed] [BIT] NOT NULL,
    [FirstName] [NVARCHAR](MAX) NOT NULL,
    [LastName] [NVARCHAR](MAX) NOT NULL,
    [LastSignIn] [DATETIME2](7) NOT NULL,
    [LockoutEnabled] [BIT] NOT NULL,
    [LockoutEnd] [DATETIMEOFFSET](7) NULL,
    [NormalizedEmail] [NVARCHAR](256) NULL,
    [NormalizedUserName] [NVARCHAR](256) NULL,
    [PasswordHash] [NVARCHAR](MAX) NULL,
    [SecurityStamp] [NVARCHAR](MAX) NULL,
    [TimeZone] [NVARCHAR](64) NOT NULL DEFAULT (N'Europe/London'),
    [TwoFactorEnabled] [BIT] NOT NULL,
    [UserName] [NVARCHAR](256) NULL,
    [LastInfoUpdate] [DATETIME] NOT NULL
)

У меня есть около миллиона строк в этой таблице, и я хочу применить некластеризованный индекс к столбцу [LastInfoUpdate].

Итак, я создал некластеризованный индекс с помощью этой команды:

CREATE NONCLUSTERED INDEX IX_ProductVendor_VendorID1   
ON [dbo].[TestUsers] (LastInfoUpdate)
INCLUDE(Email)

И как только я пытаюсь выполнить простой запрос, подобный этому:

  SELECT [LastInfoUpdate]
  FROM [dbo].[TestUsers]
  WHERE [LastInfoUpdate] >= GETUTCDATE()

Я получаю тот же результат по времени, что и без индекса.Согласно SQL Server Profiler с db выполняет поиск по индексу при использовании индекса и просто использует меньше ресурсов ЦП по сравнению с регистром без индекса, но для меня важно время.Во сколько же?Что я делаю не так?

План выполнения сканирования таблицы

План выполнения сканирования индекса

Индексискать файл плана выполнения

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

«ГДЕ [LastInfoUpdate]> = GETUTCDATE ()» может вернуть много результатов.В этом случае сканирование таблицы может быть быстрее, чем поиск по индексу и последующее добавление информации из табличных данных.Добавляя запрашиваемую информацию в индекс, вы можете избежать дорогостоящего последующего просмотра табличных данных.

0 голосов
/ 24 октября 2018

Просто создайте следующий индекс:

CREATE INDEX IX_Users_EventDate ON Users(EventDate)
INCLUDE (EventId)

И следующий запрос будет быстрым:

SELECT EventId, EventDate
FROM Users
WHERE EventDate <= GETUTCDATE()

Поскольку индекс является индексом покрытия.

Ключ индекса покрытия должен включать столбцы, на которые есть ссылки в предложениях WHERE и ORDER BY.И индекс покрытия должен включать все столбцы, на которые есть ссылки в списке SELECT.

Отправленный вами запрос не соответствует планам запросов, которые вы связали.Планы запроса предназначены для вышеуказанного запроса.

Еще одна вещь, которую необходимо учитывать, - это количество записей, возвращаемых запросом.Если их много, запрос не может быть достаточно быстрым, поскольку ему нужно прочитать все данные и отправить их в сеть.

0 голосов
/ 24 октября 2018

Попробуйте использовать ColumnStore индекс.Это быстрее, когда вы хотите получить некоторый диапазон столбцов:

CREATE NONCLUSTERED COLUMNSTORE INDEX 
    [csi_User_LastInfoUpdate_Email] ON 
    [dbo].[User] ( [LastInfoUpdate], [Email] )WITH 
    (DROP_EXISTING = OFF, COMPRESSION_DELAY = 0) ON [PRIMARY]

Статья об индексе хранилища столбцов.

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