Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Кластерное поле в некалстерном индексе  [new]
Kudep
Member

Откуда: From Russia
Сообщений: 146
Добрый день,

Есть таблица с полями OrderId, ClientId, OrderDate.
Есть калстерный индекс по полю OrderId.
Есть некластерный индекс по полям OrderDate, OrderId. Инклудед полей нет.

Я хочу удалить из некластерного индекса поле OrderId, так как
1. Оно и так присутствует в любом некластерном индексе на уровне листьев
2. Его явное указание в некластерном индексе ведет к увеличению его размера кол-ва io операций.
Подскажите, верны ли данные рассуждения?
19 сен 12, 09:17    [13186261]     Ответить | Цитировать Сообщить модератору
 Re: Кластерное поле в некалстерном индексе  [new]
gang
Member

Откуда:
Сообщений: 1394
Kudep,

Практика - лучшая проверка теории.

+
set nocount on
declare @n int
set @n=1000; --Требуемое количество строк.
with cte (v) as 
(select 1 v union all select v+1 from cte where v<@n  ) 


select 

 IDENTITY(int, 1,1) AS  OrderId  --Identity поле для ключа
,ABS(CAST(NEWID() AS binary(8)) %1000/*maximum*/)+1 as ClientId --квази-случайные числа
,dateadd(ss,-CEILING( abs(convert(float,convert(int,convert(varbinary(max),NEWID ())))/50)), GETDATE()) as OrderDate --квази-случайные даты
into #newtable 
from cte OPTION (MAXRECURSION 0)
go
create clustered index IX_Clust on #newtable (OrderId)
create nonclustered index IX_NonClust on #newtable (OrderDate, OrderId)
select OrderDate, OrderId from #newtable where OrderId>10 and OrderDate>'2010-01-01'
go

drop table #newtable
go
set nocount on
declare @n int
set @n=1000; --Требуемое количество строк.
with cte (v) as 
(select 1 v union all select v+1 from cte where v<@n  ) 


select 

 IDENTITY(int, 1,1) AS  OrderId  --Identity поле для ключа
,ABS(CAST(NEWID() AS binary(8)) %1000/*maximum*/)+1 as ClientId --квази-случайные числа
,dateadd(ss,-CEILING( abs(convert(float,convert(int,convert(varbinary(max),NEWID ())))/50)), GETDATE()) as OrderDate --квази-случайные даты
into #newtable 
from cte OPTION (MAXRECURSION 0)
go
create clustered index IX_Clust on #newtable (OrderId)
create nonclustered index IX_NonClust on #newtable (OrderDate)
select OrderDate, OrderId from #newtable where OrderId>10 and OrderDate>'2010-01-01'
go
drop table #newtable


В обоих вариантах индекса (при условии что запрос не выбирает неключевых полей) происходит индекс сик по некластерному индеку.

По поводу увеличения размера индекса - не уверен вполне что ключ кластерного индекса при явном указании в некластерном таки дублируется. Можно для проверки попробовать почитать страницы индекса через dbcc page.
19 сен 12, 09:44    [13186423]     Ответить | Цитировать Сообщить модератору
 Re: Кластерное поле в некалстерном индексе  [new]
Kudep
Member

Откуда: From Russia
Сообщений: 146
Что касается размера индекса, то похоже, что явное указание OrderId в некластерном индексе не влияет на его размер.
Смотрел так:
select ps.reserved_page_count from sys.indexes i
join sys.dm_db_partition_stats ps on i.object_id = ps.object_id and i.index_id = ps.index_id
where i.name = 'my_index_name'

Далее убирал\добавлял поле OrderId в индекс. Значение reserved_page_count при этом не изменялось. Попробовал добавить в индекс другое поле из таблицы, значение reserved_page_count увеличилось.

А еще такой вопрос, если все-таки удалить OrderId из некластерного индекса, может такое быть, что результат некоторых выборок, для которых использовался данный индекс, поменяется? Я имею в виду, что записи в индексе были дополнительно осортированы по OrderId, а после того как это поле убрали из индекса, их порядок мог измениться?
PS: сортировка в кластерном индексе по полю OrderId такая же как в некластерном ASC.
19 сен 12, 10:16    [13186644]     Ответить | Цитировать Сообщить модератору
 Re: Кластерное поле в некалстерном индексе  [new]

Guest
100% сортировка возможна только при указании order by, остальное от лукавого
19 сен 12, 10:22    [13186685]     Ответить | Цитировать Сообщить модератору
 Re: Кластерное поле в некалстерном индексе  [new]
gang
Member

Откуда:
Сообщений: 1394
Kudep,

Сортировка строк в индексе никак не связана с сортировкой результирующего набора выборки. Порядок сортировки результата однозначно определяется только через order by. Другое дело если указанный Вами в запросе order by совпадает с аналогичным в индексе - тогда время и ресурсы на сортировку расходоваться не будут.
19 сен 12, 10:24    [13186701]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить