Почему мой первичный ключ замедляет мои запросы?

Я использую SQL Server 2008 и в одной из моих таблиц я реализовал (кластеризованный) первичный ключ для его идентификатора. Вот описание таблицы:

Идентификатор: - IdentifierId int NOT NULL PK - Псевдоним nvarchar(200) - DataType int NOT NULL

Я сделал два индекса: один для Alias, а другой для DataType. Однако я просто заметил что-то странное. При выполнении следующего запроса:

SELECT * FROM IDENTIFIER WHERE DataType = 1

На самом деле запрос выполняется медленнее с индексами и первичным ключом, чем без них; это займет примерно 10 секунд дольше! Индексы не фрагментированы - я проверил - и я тоже использую это

GO
CHECKPOINT;
GO
DBCC DROPCLEANBUFFERS;
GO
DBCC FREEPROCCACHE;
GO

перед самим запросом.

Эта таблица довольно большая и содержит несколько миллионов записей. Индексы и PK играют жизненно важную роль в большинстве запросов, но в этом случае я не могу понять, почему запрос выполняется с ними медленнее. Есть идеи?

заранее спасибо

РЕДАКТИРОВАТЬ: план выполнения показывает, что используется только кластеризованный индекс, а переменная DataType в настоящее время достигает 150.

2 ответа

Решение

Создать составной некластеризованный покрывающий индекс на DataType с включенным столбцом Aliasи удалите отдельные индексы на Alias а также DataType колонки:

CREATE NONCLUSTERED INDEX NC_DataType_I_Alias 
    ON tblIdentifier(DataType) INCLUDE (Alias)

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

Таким образом, ключом к производительности является наличие некластеризованного индекса (на самом деле это плохое имя, поскольку некластеризованные индексы часто намного превосходят кластерные индексы) и INCLUDE дополнительные столбцы в индексе, чтобы он стал covering, В случае до SQL Server 2005 вам просто нужно добавить столбцы в конец индекса.

Итак, в основном, первичный ключ хорош, но не обязательно должен определять ваш выбор кластеризации, и вам, как правило, нужно полагаться на некластеризованные индексы (с соответствующим INCLUDEстолбцы ed) для повышения производительности при выполнении самых выборочных операций с кластеризованным индексом, предназначенным для наименее селективного и наиболее часто сортируемого случая.

Другие вопросы по тегам