Почему мой первичный ключ замедляет мои запросы?
Я использую 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) для повышения производительности при выполнении самых выборочных операций с кластеризованным индексом, предназначенным для наименее селективного и наиболее часто сортируемого случая.