Реферат: Новые возможности MS SQL Server 2004 "Yukon"

Ряд настроек индекса, которые ранее задавались с помощью специальной хранимой процедуры, теперь можно указать напрямую, при создании или изменении индекса. ALLOW_ROW_LOCKS разрешает или запрещает блокировку индекса на уровне строк, а ALLOW_PAGE_LOCKS – на уровне страниц данных.

MAXDOP

MAXDOP (max degree of parallelism) – максимальное количество процессоров, используемых при построении плана выполнения запроса. В предыдущих версиях задать этот параметр напрямую при работе с индексами было нельзя – использовались настройки для всей системы, задаваемые через системную хранимую процедуру sp_configure. Теперь же этот параметр можно указать отдельно для каждого индекса. Здесь имеется в виду количество процессоров, которое будет использоваться непосредственно при создании или изменении индекса, а не при последующей работе с ним. Что называется, «пустячок, а приятно» ;)

Index include

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

В Microsoft SQL Server индекс представляет собой B+tree, узлы которого состоят из ключевых полей, а в листьях (узлах самого последнего уровня) содержатся ссылки на записи таблицы.

Индекс может быть двух типов, кластерный (clustered) и не кластерный.

Кластерный индекс отличается от некластерного тем, что в листьях этого индекса содержатся не ссылки на записи в таблице, а сами записи. Таким образом, при наличии кластерного индекса записи в таблице выстраиваются в порядке ключей такого индекса (строго говоря это не совсем так, но в первом приближении верно). По очевидным причинам кластерный индекс может быть только один на таблицу. Идентификация конкретной записи в таблице также находится в прямой зависимости от наличия кластерного индекса. Если кластерного индекса нет, то запись находится по уникальному идентификатору записи – RID, который однозначно определяет ее положение в файле данных. Если же кластерный индекс в таблице присутствует, то физическое место этой записи не постоянно, а, следовательно, использовать RID не очень практично, поскольку его пришлось бы обновлять во всех индексах при каждом изменении. Поэтому запись идентифицируется по ключу кластерного индекса.

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

Поле, которое надо выбрать, совпадает с полем, по которому нужно осуществить поиск, и по этому полю построен индекс.

SELECT LastName FROM employees WHERE LastName = 'Callahan'

План такого запроса прост и незатейлив:

|--Index Seek(OBJECT:([Employees].[LastName]),

SEEK:([Employees].[LastName]=Convert([@1])) ORDERED FORWARD)

Нужное значение просто находится по индексу.

Поле, которое необходимо просмотреть, не совпадает с полем, по которому нужно искать, но при этом по полю поиска построен кластерный индекс.

SELECT LastName FROM Employees WHERE EmployeeID = 8

План такого запроса также не отличается излишней сложностью:

|--Clustered Index Seek(OBJECT:([Employees].[PK_Employees]),

SEEK:([Employees].[EmployeeID]=Convert([@1])) ORDERED FORWARD)

Все закономерно – идет поиск по кластерному индексу, а затем извлекается нужное поле из этого индекса.

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

SELECT LastName FROM Employees WHERE PostalCode = '98105'

Вот здесь уже серверу приходится совершать дополнительные телодвижения, и план запроса немного усложняется:

|--Bookmark Lookup(BOOKMARK:([Bmk1000]), OBJECT:([Employees]))

|--Index Seek(OBJECT:([Employees].[PostalCode]),

SEEK:([Employees].[PostalCode]=Convert([@1])) ORDERED FORWARD)

Сначала по индексу находится нужная запись, а точнее, не запись, а ссылка на запись. При этом значения поля, которое на самом деле надо достать из таблицы, по-прежнему нет, так как поле поиска не является нужным полем, как это было в первом случае. На данный момент у сервера, как уже говорилось, есть только ссылка, и чтобы извлечь нужное поле, надо выполнить еще одну операцию – bookmark lookup. Стоимость этой операции в некоторых случаях может быть очень высока, например, в этом запросе она составляет половину всей его стоимости (49%). В случае с кластерным индексом такого не происходит, потому что в листьях кластерного индекса содержится вся запись, а значит, ничего искать уже не надо.

ПРИМЕЧАНИЕ

Естественно, в реальных задачах, планы выполнения запросов могут быть гораздо более сложными. Многое зависит от селективности индексов, статистики, доступной памяти и других факторов, но рассмотрение этих высоких материй выходят за рамки данной статьи.

В силу того, что стоимость дополнительной операции по извлечению полей, не входящих в индекс, может быть довольно высока, то иногда приходится от нее избавляться. В предыдущих версиях Microsoft SQL Server был, фактически, только один способ избавится от дорогого bookmark lookup. Для этого строился составной (композитный) индекс, первым полем или полями которого являлись поля, входящие в условие поиска, а затем шли поля, которые необходимо было извлечь. Поскольку в этом случае все нужные значения уже содержатся в ключе индекса, то потребность в дополнительных операциях отпадает. Но при подобном подходе вырастает размер ключей индекса, из-за этого увеличивается размер базы и снижается эффективность индексных операций. Вдобавок, максимальный размер ключа индекса не может превышать 900 байт, и вылезти за эти границы довольно просто.

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

К-во Просмотров: 206
Бесплатно скачать Реферат: Новые возможности MS SQL Server 2004 "Yukon"