Какова цель некластеризованного индекса без полей? - PullRequest
0 голосов
/ 25 февраля 2019

База данных унаследованного приложения, которое я недавно начал обслуживать, имеет 2 индекса, область действия которых я не понимаю.

Таблица, для которой создаются индексы, выглядит следующим образом (это таблица, в которой хранятся ссылки междуОбъекты SW (это позволяет, например, связать клиента и 2 заказа, поэтому устанавливается связь между клиентом и 2 заказами):

CREATE TABLE [LINKS](
    [LINK_ID] [int] NOT NULL, -- Counter Primary Key
    [LINK_TYPE] [int] NOT NULL,-- Foreign Key to "link types" table
    [ID_LINK_FROM] [int] NOT NULL, -- this is not FK, just an int
    [ID_LINK_TO] [int] NOT NULL, -- this is not FK, just an int
    [ID_LINK_TO_DETAIL] [int] NULL, -- this is not FK, just an int
    [HAS_PRIORITY] [nchar](1) NOT NULL -- this is 'Y'/'N' "Boolean-like"
)

таблица имеет счетчик PK и три целых поля, которыена самом деле отсутствуют FK, потому что в зависимости от LINK_TYPE место назначения - это другая таблица. Конечно, полным решением будет нормализация БД, но сейчас это не вариант.

В этой таблице явно представлены проблемы с производительностьюво всех запросах, которые используют его в JOIN. Чтобы попытаться решить эту проблему, кто-то в прошлом создал 2 (бесполезных, с моей точки зрения) индекса:

CREATE NONCLUSTERED INDEX [IDX_LINKS_ID_LINK_FROM] ON [dbo].[LINKS]
(
    [ID_LINK_FROM] ASC
)

и

CREATE NONCLUSTERED INDEX [IDX_LINKS_ID_LINK_TO] ON [dbo].[LINKS]
(
    [ID_LINK_TO] ASC
)

Эти индексы содержат только «недостающий FK», поэтому они бесполезны, потому что недостающие FK наверняка используются для JOIN, но затемлюбое другое поле отсутствует в индексе.

Так что мой вопрос "обратного инжиниринга" таков: вы подтверждаете, что эти 2 индекса бесполезны?

Насколько мне известно, следующие 2 были бы лучше "«исправление» из-за отсутствия нормализации БД:

CREATE NONCLUSTERED INDEX [IDX_LINKS_ID_LINK_FROM] ON [dbo].[LINKS]
(
    [ID_LINK_FROM] ASC
)
INCLUDE ( LINK_TYPE,
ID_LINK_TO,
ID_LINK_TO_DETAIL,
HAS_PRIORITY)

и

CREATE NONCLUSTERED INDEX [IDX_LINKS_ID_LINK_TO] ON [dbo].[LINKS]
(
    [ID_LINK_TO] ASC
)
INCLUDE ( LINK_TYPE,
ID_LINK_FROM,
ID_LINK_TO_DETAIL,
HAS_PRIORITY)

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

Можете ли вы подтвердить, что я на правильном пути?

С первых измерений, которые я провел по некоторым "значимым запросам", я вижу улучшение, но я хотел бы получить некоторые отзывы, прежде чем продолжитьна этом пути.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

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

SELECT i.name, s.*
FROM sys.dm_db_index_usage_stats s
    JOIN sys.indexes i ON i.object_id = s.object_id
        AND i.index_id = s.index_id
    JOIN sys.sysindexes si ON si.id = i.object_id
        AND si.indid = i.index_id
WHERE s.object_id = OBJECT_ID('LINKS')
ORDER BY i.name
0 голосов
/ 25 февраля 2019

Существует больше применений для индексов, чем , только"покрывающие" индексы, что и есть те, которые вы предлагаете.

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

Имейте в виду, что INCLUDE не существовало до SQL Server 2008. Некластеризованные индексы датируются гораздо дольше, чем это.

Как и во всех решениях по индексированию, только вы находитесь в нужном месте, чтобы определить все шаблоны запросов / изменений в ваших данных и можете проверить предлагаемые изменения в индексировании.Убедитесь, что вы всегда профилируете репрезентативную выборку запросов, а не только ту, которая, по вашему мнению, будет ускорена при конкретном изменении индекса.


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

Содержание основной книги (листья) + Оглавление (не листья) составляют кластерный индекс.

Но книга может также иметь один или более фактических индексов., как правило, находится в конце книги.Это позволит вам выполнить поиск, ориентированный, скажем, по ключевым словам, и скажет вам, на каких страницах книги перейти, на какое упоминание этого ключевого слова.Вам по-прежнему нужно перейти к основному содержанию книги, чтобы получить необходимую информацию.

книжные индексы = некластеризованные индексы.Поиск ключевого слова в индексе = поиск индекса / сканирование.Ссылка на страницы в содержании = поиск по закладкам.

Некластеризованный индекс с INCLUDE столбцами немного сложен в этой аналогии, но на рисунке, например, "глоссарий", который может объединить несколько терминов,разверните их определения более подробно и в них есть ссылки «см. также», которые снова являются ссылками на страницы в содержании основной книги.

...