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

Откуда: С-Петербург
Сообщений: 902
Господа, существует такой вот селект.
select distinct lastname,firstname,surname,[date],pin

from indexinfo
where lastname=isnull(@idLN,lastname)
and surname=isnull(@idSN,surname)
and firstname=isnull(@idFN,firstname)
and date=isnull(@date,date)

Все поля, кроме даты - int. Стоит кластерный индекс на lastname+firstname. Если снять первый "страховочный" isnull, то запрос станет выполняться в сотню раз быстрее. При этом в обоих случаях план запроса не меняется, идет сканирование кластерного индекса. Да и с чего ему меняться?
Что же происходит? И как этого избежать? Ведь в запросе надо предусмотреть возможность опущения параметра.
17 мар 04, 16:21    [583250]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
BootMaker
Member

Откуда: С-Петербург
Сообщений: 902
Я, конечно, вижу отличный вариант создания отдельной процедуры с этим селектом, которая получает входными данными все переменные условий и каждый раз рекомпилируется, исходя из значений пременных.
Но нельзя ли проще?
17 мар 04, 16:25    [583269]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Glory
Member

Откуда:
Сообщений: 104760
Что-то мне как-то не верится в разницу времени выполнения при одинаковых планах. Можно увидеть результат работы следующего скрипта ?

SET SHOWPLAN_TEXT ON
GO
select distinct lastname,firstname,surname,[date],pin
from indexinfo
where lastname=isnull(@idLN,lastname)
and surname=isnull(@idSN,surname)
and firstname=isnull(@idFN,firstname)
and date=isnull(@date,date)

select distinct lastname,firstname,surname,[date],pin
from indexinfo
where lastname=@idLN
and surname=isnull(@idSN,surname)
and firstname=isnull(@idFN,firstname)
and date=isnull(@date,date)

GO
SET SHOWPLAN_TEXT OFF
GO
17 мар 04, 16:28    [583281]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
хы... если снять "страховочный" изнул... то будет индекссик по первому полю (второе поле индекса будет сканироваться), в этом я уверен...


для спящего время бодрствования равносильно сну
17 мар 04, 16:30    [583290]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
Попробуйте такой вариант:

select distinct
lastname,firstname,surname,[date],pin
from
indexinfo
where
(lastname=@idLN or @idLN is null)
and (surname=@idSN or @idSN is null)
and (firstname=@idFN or @idFN is null)
and (date=@date or @date is null)
17 мар 04, 16:30    [583294]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
2 Trong
все равно индекс скан... =\
изворачиваться через union... больше никак... или динамический запрос делать в зависимости от параметров...

для спящего время бодрствования равносильно сну
17 мар 04, 16:35    [583310]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Trong
Member

Откуда: Novosibirsk
Сообщений: 759
автор
все равно индекс скан... =\

Не соглашусь. У оптимизатора обычно хватает ума разрулить эту ситуацию.
17 мар 04, 16:39    [583324]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Алексей2003
Member

Откуда: Москва
Сообщений: 5645
етому согласитесь или нет?

declare @i varchar(20)

set @i = 'f'
select emp_id from employee where lname = @i or @i is null
go
declare @i varchar(20)
set @i = 'f'
select emp_id from employee where lname = @i --or @i is null


уж как только не изголялся...


для спящего время бодрствования равносильно сну
17 мар 04, 16:44    [583346]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
BootMaker
Member

Откуда: С-Петербург
Сообщений: 902
2 Glory
Это я, сгоряча, конечно, про одинаковые планы.
В случае с isnull-ом:
       |--Clustered Index Scan(OBJECT:([MegaSKM].[dbo].[IndexInfo].[IX_IndexInfo]), WHERE:((([IndexInfo].[LastName]=isnull([@idln], [IndexInfo].[LastName]) AND [IndexInfo].[SurName]=isnull([@idsn], [IndexInfo].[SurName])) AND [IndexInfo].[FirstName]=isnull



без него:

|--Clustered Index Seek(OBJECT:([MegaSKM].[dbo].[IndexInfo].[IX_IndexInfo]), SEEK:([IndexInfo].[LastName]=[@idln]), WHERE:(([IndexInfo].[FirstName]=isnull([@idfn], [IndexInfo].[FirstName]) AND [IndexInfo].[Date]=isnull([@date], [IndexInfo].[Date]))
17 мар 04, 16:51    [583366]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
BootMaker
Member

Откуда: С-Петербург
Сообщений: 902
Так что же делать, господа?
Неужели все через динамические запросы решать?
Я в печали.
18 мар 04, 15:48    [585540]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Crip
Member

Откуда:
Сообщений: 2490
2BookMaker
Ага либо динамические либо условный переход
IF @idLN is not null...
Вариант от Trong в зависимости от статистик будет давать либо Index Scan либо Clustered Index Scan. Причем чаще последний, что эквивалентно lastname=isnull(@idLN,lastname)
18 мар 04, 16:00    [585578]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
AISOFT
Guest
Hint
18 мар 04, 16:16    [585619]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
BootMaker
Member

Откуда: С-Петербург
Сообщений: 902
Все козлы...
Это я не вам, господа, это я про жизнь в целом. И про оптимизатор в частности.
Спасибо за участие. Отпишусь, когда сотворю что-нибудь толковое.
18 мар 04, 16:18    [585629]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
Crip
Member

Откуда:
Сообщений: 2490
2AISOFT
Хинт погоды не сделает... Оптимизатор не настолько туп...Если надо то заменит Clustered Index Scan на Index Scan , а большего вы хинтом и не добьетесь.
18 мар 04, 16:31    [585676]     Ответить | Цитировать Сообщить модератору
 Re: Про isnull  [new]
AISOFT
Guest
А большег, в данном случае, и не надо.
18 мар 04, 17:58    [585976]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить