Вопросы и ответы по SQL Некластеризованные индексы и сохранение полномочий

Салим Хакани (Saleem Hakani) and Дэн Каролло (Dan Carollo)

Некластеризованные индексы и области их применения

В: Что такое некластеризованные индексы? Каковы преимущества и недостатки их использования?

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

Кроме того, у некластеризованных индексов есть два ограничения: в индекс могут быть включены только 16 столбцов, и максимальный размер ключа индекса не может превышать 900 байтов. Так что это значит? Давайте взглянем, что произойдет, при попытке проиндексировать следующие столбцы в таблице Movie из примера базы данных MovieList: MovieTitle NVarchar(50), DirectorName NVarchar(50), ShortStory NVarchar(400).

Предположим, что для создания таблицы выдается следующий оператор:

Use MovieList;
CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName, ShortStory); 

При этом появится следующее сообщение об ошибке: «Предупреждение! Максимальная длинна ключа равна 900 байтам. Индекс 'Movie_IDX' имеет максимальную длину 1000 байтов. Для некоторых комбинаций больших значений операция вставки/обновления закончится сбоем." Будет выдано приведенное выше сообщение, поскольку тип данных "nvarchar" расходует 2 байта на каждый символ, и индекс, содержащий три предыдущих столбца, выйдет за лимит в 900 байтов.

После выпуска SQL Server® 2005 появилась возможность преодолеть эту проблему путем добавления столбцов к предложению INCLUDE. Это очень полезная функция, если необходимо преодолеть ограничения и по размеру и по столбцам. Все это можно сделать, выполнив следующий оператор:

CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName) INCLUDE (ShortStory);

Важно помнить, что при использовании предложения INCLUDE в ходе создания индекса механизм СУБД не рассматривает неключевые столбцы при вычислении числа ключевых столбцов индекса или размера ключа индекса.

Более полезную информацию о некластеризованных индексах можно найти на страницах "Non-clustered Indexes" («Некластеризованные индексы») на msdn2.microsoft.com/aa174537 и "Using Non-clustered Indexes" («Использование некластеризованных индексов») на msdn2.microsoft.com/aa933130. Советы по оптимизации индексов приведены на странице sql-server-performance.com/optimizing_ indexes.asp.

Сохранение данных полномочий

В: Как можно избежать потери полномочий при повторной инициализации подписки? Я несколько раз сталкивался с проблемой потери всех данных полномочий при повторной инициализации снимка.

О: По умолчанию, все объекты в базе данных подписки сбрасываются и создаются заново при повторной инициализации подписки. Но из этой ситуации можно выйти двумя способами.

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

Во-вторых, можно настроить подписку, чтобы она не сбрасывала объекты при повторной инициализации. Чтобы сделать это, можно использовать системную хранимую процедуру SP_CHANGEARTICLE с целью настройки значения PRE_CREATION_CMD для параметра @PROPERTY и значения NONE, DELETE или TRUNCATE для параметра @Value.

Кроме того, в диалоговом окне «Свойства статьи» в разделе конечного объекта следует выбрать значение "Keep existing object unchanged, delete data. If article has a row filter, delete only what matches the filter. Truncate all data in the existing object.". «Оставить существующий объект без изменений, удалить данные. При наличии фильтра строк удалить только совпадающие с фильтром. Усечь все данные в существующем объекте.» Не забудьте испытать это в тестовой среде, а при необходимости дополнительных пояснений ознакомьтесь с последней версией электронной документации по SQL Server на предмет свежих сведений.

Салим Хакани (Saleem Hakani) – старший инженер по базам данных, старший специалист по решению проблем и руководитель всемирного сообщества Microsoft SQL Server, обладающий 14-летним стажем в области систем баз данных. Он ведет внешний веб-узел сообщества SQL Server sqlcommunity.com , связаться с ним можно по адресу Saleem@sqlcommunity.com.

Дэн Каролло (Dan Carollo) – инженер-эксплуатационник и администратор базы данных SQL Server, работающий с группой изучения вредоносного программного обеспечения в среде Windows и реагирования на него в корпорации Майкрософт. Он является сертифицированным преподавателем Майкрософт (MCT) по SQL Server.

© 2008 Корпорация Майкрософт и компания CMP Media, LLC. Все права защищены; полное или частичное воспроизведение без разрешения запрещено.