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

Откуда:
Сообщений: 322
Столкнулся с следующей проблеммой...

SELECT TOP 1 FROM xxx WHERE date='YYYYMMDD' ORDER BY yyy
и
DECLARE @d datetime
SET @d = 'YYYYMMDD'
SELECT TOP 1 FROM xxx WHERE date=@d ORDER BY yyy

Второй вариант на 250 мс дольше... как это победить?

P.S. date участвует в кластерном PK
14 авг 04, 12:17    [881974]     Ответить | Цитировать Сообщить модератору
 Re: 250мс  [new]
Слон
Member

Откуда:
Сообщений: 717
Сравни Execution Plans. В первом случае скорее всего, так как известно значение, исполняется Index Seek, во втором - Scan. Я позволю предположить, что этот столбец позволяет NULL и на 80% заполнен значениями NULL или другим default значением. Поэтому, optimizer выбирает наиболее универсальный план.

Если я прав, то добавка AND date IS NOT NULL (или date <> [default value])должна помочь

-- Слон
14 авг 04, 12:40    [881989]     Ответить | Цитировать Сообщить модератору
 Re: 250мс  [new]
sparrow
Member

Откуда: Россия, Красноярск.
Сообщений: 21759
1 нормализация данных и изменение структуры данных
2 date поставить первым в кластерном индексе
3 создать индес по date
4 использовать динамический sql

ps. 2,3 могут создать проблеммы в других местах. 4 перекомпиляции
14 авг 04, 12:41    [881992]     Ответить | Цитировать Сообщить модератору
 Re: 250мс  [new]
Paul Chabinsky
Member

Откуда:
Сообщений: 322
Вот пример:
create table [sequensenum] (
	[sen_seq_id] [int] not null ,
	[sen_num] [int] not null ,
	[sen_date] [datetime] not null ,
	constraint [pk_sequensenum] primary key  clustered 
	(
		[sen_seq_id],
		[sen_num]
	)
)
go
begin tran
declare @i int
set @i = 1
while @i <=365*800
	begin
		insert into [sequensenum]([sen_seq_id], [sen_num], [sen_date])
		values(1, @i, dateadd(dd,round(@i/800,0),'20040101'))
		set @i = @i+1
	end
commit tran
go
select top 1 n.*
	from sequensenum n
		where (sen_seq_id = 1) and (sen_date >= '20041231')
			order by sen_num asc
go
declare @d datetime
select @d = '20041231'
select top 1 n.*
	from sequensenum n
		where (sen_seq_id = 1) and (sen_date >= @d)
			order by sen_num asc
go
14 авг 04, 13:06    [881997]     Ответить | Цитировать Сообщить модератору
 Re: 250мс  [new]
Glory
Member

Откуда:
Сообщений: 104760
https://www.sql.ru/articles/article.aspx?aid=1535
14 авг 04, 13:33    [882010]     Ответить | Цитировать Сообщить модератору
 Re: 250мс  [new]
Paul Chabinsky
Member

Откуда:
Сообщений: 322
2Glory
Ты как всегда ве бест :)

Всем спасибо...
14 авг 04, 13:40    [882016]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить