Почему мой первичный ключ замедляет мои запросы? - PullRequest
4 голосов
/ 08 июня 2009

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

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

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

SELECT * FROM IDENTIFIER WHERE DataType = 1

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

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

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

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

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

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

Ответы [ 2 ]

7 голосов
/ 08 июня 2009

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

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

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

5 голосов
/ 08 июня 2009

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

CREATE NONCLUSTERED INDEX NC_DataType_I_Alias 
    ON tblIdentifier(DataType) INCLUDE (Alias)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...