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

Откуда:
Сообщений: 16
Доброй ночи уважаемые форумчане.
Такой простой вопрос:
есть таблица [T] в несколько млн строк, в ней поле msgTime типа Datetime - кластерный индекс на этой таблице.
Почему при таком запросе (вернуть запись с наибольшим значением )
SELECT TOP(1) smgTime FROM T ORDER BY msgTime desc

происходит полное сканирование индекса?
15 окт 12, 23:16    [13323170]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
а вы где то увидели условия поиска ?
15 окт 12, 23:21    [13323188]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37050
План покажите актуальный.
15 окт 12, 23:22    [13323191]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
4k
Member

Откуда:
Сообщений: 16
План выполнения в файле.

Есть ли способ без сканирования индекса вытащить наибольшее значение smgTime ?

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

К сообщению приложен файл. Размер - 47Kb
15 окт 12, 23:43    [13323255]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
DeColo®es
Member

Откуда: Москва
Сообщений: 5499
Блог
4k,

Сканирование в вашем случае закончится ровно на первой записи.

IndexSeek был бы, если бы Вы искали конкретное значение.
А тут нужно выбрать просто первое с конца. Оптимальнее плана придумать просто нереально - у Вас будет чтение всего одной страницы данных.
15 окт 12, 23:56    [13323309]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
IF Exists(SELECT FROM sys.Plan WHERE OperatorType = 'Scan')
  EXEC [Паника];
16 окт 12, 00:02    [13323327]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Mnior
IF Exists(SELECT FROM sys.Plan WHERE OperatorType = 'Scan')
  EXEC [Паника];
Плохо только то, что в sys.dm_db_index_usage_stats обновится счетчик user_scans, а не user_seeks, из-за чего данные в этой dmv становятся весьма двусмысленными для какого либо анализа.
16 окт 12, 04:11    [13323819]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Mind
Плохо только то, что в sys.dm_db_index_usage_stats обновится счетчик user_scans, а не user_seeks, из-за чего данные в этой dmv становятся весьма двусмысленными для какого либо анализа.
Хорошая шутка.
16 окт 12, 10:29    [13324663]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
4k
Member

Откуда:
Сообщений: 16
Всем проявившим участие - спасибо. Как написал Mnior - был напуган)
16 окт 12, 22:35    [13329675]     Ответить | Цитировать Сообщить модератору
 Re: order by на кластерном индексе  [new]
Ray D
Member

Откуда: from the middle of nowhere
Сообщений: 3598
Блог
А вот здесь полное сканирование кластерного индекса в order_details? ;)

create table dbo.orders	(
		order_id	int		identity	primary key nonclustered
	,	order_date	datetime not null
)
go

create clustered index ix_order_date on dbo.orders(order_date)
go

create table dbo.order_details	(
		order_id	int		not null
	,	item_id		int		not null
)
go

create clustered index ix_order_id on dbo.order_details(order_id)
go

insert into dbo.orders	(
		order_date
)
select top (10000)
		dateadd(dd, abs(checksum(newid())) % 365, '20120101')
from sys.objects s1
cross join sys.objects s2
cross join sys.objects s3
go

insert into dbo.order_details (
		order_id
	,	item_id
)
select top (100000)
		abs(checksum(newid())) % 10000 + 1
	,	abs(checksum(newid())) % 5
from sys.objects s1
cross join sys.objects s2
cross join sys.objects s3
go

select	o.order_id
	,	o.order_date
	,	od.item_id
	,	od.order_id
from dbo.orders o
inner merge join dbo.order_details od on od.order_id = o.order_id
where	o.order_date	>=	'20120501'
	and	o.order_date	<	'20120601'
go
17 окт 12, 01:42    [13330390]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить