Содержит ли некластерный индекс SQL Server 2008 поля кластерного индекса? - PullRequest
5 голосов
/ 02 января 2011

ОК, мне нужно это изложить еще раз.Я читал статьи в Интернете и до сих пор не нашел однозначного ответа.

В SQL Server 2008 у меня есть «основная» таблица с записями около 50 тыс. И большим количеством операций чтения, которыеиспользуется одинаково во всех запросах.Эти данные обновляются раз в месяц и читаются сотни раз в секунду.

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

КЛАСТЕРНЫЙ ИНДЕКС

Field1 int
Field2 int
Field3 int
Field4 int
Field5 int

Теперь данных не намного больше, чем это, поэтому имеет смысл просто добавить лишнюю парустолбцы в «Включенные столбцы», но SQL Server не позволяет включать столбцы в кластеризованном индексе.

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

ИНДЕКС ПОКРЫТИЯ (не кластеризовано)

Field1 int
Field2 int
Field3 int
Field4 int
Field5 int

ВКЛЮЧЕНО КОЛОННЫ

Field6 varchar(96)
Field7 varchar(96)

в некластеризованном индексе УЖЕ есть столбцы из кластеризованного индекса, определенные в нем?

Если да, то как вообще можно создать этот второй индекс без столбцов (кроме того, что уже есть в кластеризованном индексе)?Другими словами, я хотел бы сказать: «Этот индекс точно такой же, как кластеризованный индекс ... с парой включенных столбцов».

Или было бы лучше просто поместить ВСЕ изстолбцы в кластерный индекс (включая два, которые не идентифицируют запись)?Столбцы varchar обновляются чаще (несколько раз в день, а не раз в месяц), поэтому я бы хотел, чтобы они не попадали в кластерный индекс, но я думаю, что они достаточно глубоки, чтобы не влиять надерева индексов достаточно, чтобы вызвать любое изменение баланса при изменении.

Итак, существует ли эффективный способ настроить эти индексы, чтобы все столбцы этой таблицы были доступны через индекс, не возвращаясь к таблице

Ответы [ 4 ]

5 голосов
/ 02 января 2011

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

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

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

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

Возможно, вам лучше использовать искусственное значение (Identity) для кластеризованного ключа и использовать уникальный индекс NC для обеспечения уникальности, которую вы имеете с помощью кластерного ключа из 5 полей.

4 голосов
/ 02 января 2011

Кластерный индекс не требует включений. Включает в себя средства хранения дополнительных данных на самом низком уровне дерева индексов. Это - это данные в кластерном индексе. Так что вам не нужен перекрывающийся индекс

Однако, если вас беспокоит объем памяти, вам нужно уменьшить таблицу. С 50k строками я бы рассматривал суррогатный ключ smallint, начинающийся с -32768. Затем вы удаляете издержки ключа C в каждом индексе NC. Это означает, что вы можете иметь индекс покрытия, как указано в вашем вопросе.

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

Однако, если ваши данные почти статичны, тогда зачем вообще вызывать SQL Server, если проблема в производительности? Кэшируйте это. Удалите сетевую обратную связь, которая, вероятно, является вашей самой большой нагрузкой, основываясь на моих комментариях кеширования Мы производим некоторые поиски и кэширование для наших клиентов, чтобы уменьшить нагрузку на сервер (у нас 50 тыс. Записей за 20 секунд при пиковой нагрузке)

1 голос
/ 02 января 2011

Я думаю, вам нужно лучше понять индексы CLUSTERED и NONCLUSTERED. Кластерный индекс представляет собой сбалансированное дерево (B-дерево), где каждый узел содержит ключевые столбцы для индекса. Обычно и часто лучший вариант, один столбец является ключевым столбцом для индекса. все данные для каждой строки хранятся на конечном уровне (то есть на нижнем уровне) кластерного индекса. Вот почему вы не можете включить столбцы в кластерный индекс; все столбцы включены по определению.

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

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

Таким образом, для кластерного индекса вам не нужно включать все столбцы или даже много столбцов в качестве ключей в индексе. Данные уже являются частью индекса.

1 голос
/ 02 января 2011

имеет смысл просто поместить дополнительные пары столбцов в «Включенные столбцы», но SQL Server не разрешает включать столбцы в кластеризованный индекс

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

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

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

Имеет ли некластерный индекс УЖЕ столбцы из кластерного индекса, определенного в нем?

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

Итак, существует ли эффективный способ настроить эти индексы, чтобы все столбцы этой таблицы были доступны через индекс безвернуться к таблице?

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

...