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

Откуда:
Сообщений: 86
Блог
Есть два запроса

DECLARE @title NVARCHAR(500) = '"Finite" AND "Elements"'

select * from papers p
where (@title = '""' OR CONTAINS(p.name, @title))

select * from papers p
where (CONTAINS(p.name, @title))


первый работает секунд 7 второй моментально. Есть идеи почему?

От значения @title скорость не зависит.
20 янв 12, 14:00    [11939273]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
Glory
Member

Откуда:
Сообщений: 104751
А где неправильный план то ?
20 янв 12, 14:03    [11939308]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
aleks2
Guest
amakhin
Есть идеи почему?


Первый запрос повергает оптимизатор в изумление своей бессмысленностью.
Изумление длится 7 сек.
20 янв 12, 14:07    [11939359]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
denis2710
Member

Откуда: Москва
Сообщений: 3384
в первом скорей всего не используется индекс.
попробуй or поменять на union.
20 янв 12, 14:08    [11939373]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
Glory,

К сообщению приложен файл. Размер - 87Kb
20 янв 12, 14:09    [11939386]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
aleks2,
когда подрастёшь - поймешь. а вот непонятливость оптимизатора реально удивила.
20 янв 12, 14:11    [11939408]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
amakhin,

так OR очень часто приводит к "неправильному плану"


пробуйте типа:

select * from papers p
where @title = '""' 
union
select * from papers p
where CONTAINS(p.name, @title)
20 янв 12, 14:12    [11939410]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
хотя прикольно :)

Если @title = '""' то мы должны всю таблицу выбрать = скан кластерного индекса :)


Может CASE тогда стоит попробовать...
20 янв 12, 14:15    [11939448]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
SanyL, на самом деле запрос посложнее и с UNION там не прокатит
20 янв 12, 14:19    [11939488]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
SanyL, что-то не получилось у меня CASE и CONTAINS подружить.
20 янв 12, 14:21    [11939517]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
а на что жалуется?
20 янв 12, 14:26    [11939564]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
Вопрос решен благодаря StackOverflow
http://stackoverflow.com/questions/8939652/wrong-plan-for-contains-condition-in-the-ms-sql

select * from papers p
where (@title = '""' OR CONTAINS(p.name, @title)) OPTION(RECOMPILE)
20 янв 12, 14:30    [11939615]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
aleks2
Guest
amakhin
aleks2,
когда подрастёшь - поймешь.


... если б старость могла!

Фсе это уже давно и многократно обжевано: оптимизатор НЕ ЗНАЕТ содержимого @title в момент построения плана запроса.

Ну и строит... сответственно.

ЗЫ. Молодым - везде у нас дорога...
20 янв 12, 14:32    [11939642]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
denis2710
Member

Откуда: Москва
Сообщений: 3384
Более правильно сделать два запроса для @title = '""' и @title != '""'
Компилировать запрос при каждом его вызове,это не очень хорошо.
20 янв 12, 14:33    [11939651]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
Я бы не стал бы добавлять OPTION(RECOMPILE)


делалбы либо через CASE либо через IF
20 янв 12, 14:34    [11939666]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
aleks2, кто б сомневался что ты это напишешь после того как я опубликовал ссылку на объяснение и правильное решение.
20 янв 12, 14:34    [11939669]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
aleks2
Guest
SanyL
Я бы не стал бы добавлять OPTION(RECOMPILE)


делалбы либо через CASE либо через IF


Теперь будем ждать тредстартера с вопросом: а чо уменя щетчик рекомпиляций зашкаливает?
20 янв 12, 14:36    [11939694]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
amakhin
aleks2, кто б сомневался что ты это напишешь после того как я опубликовал ссылку на объяснение и правильное решение.

у вас далеко не лучшее решение.
20 янв 12, 14:39    [11939727]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
SanyL,
напишите мне, пожалуйста, запрос с CASE, у меня не получается. IF наверно не подойдёт - очень громоздко получится.
20 янв 12, 14:40    [11939749]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31949
kDnZP
amakhin
aleks2, кто б сомневался что ты это напишешь после того как я опубликовал ссылку на объяснение и правильное решение.

у вас далеко не лучшее решение.
+1
Правильный ответ сказали сразу - union

Хотя если сам запрос не очень навороченный (расходы на компиляцию небольшие) , то и так нормально.
20 янв 12, 14:42    [11939771]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
amakhin
Member

Откуда:
Сообщений: 86
Блог
alexeyvg,

вот исходный запрос, переписывать с UNION или IF достаточно непросто.

select DISTINCT p.PaperId as OuterId, p.paper_type AS PaperType, p.name as Name, p.page_begin as Page, p.open_access as OpenAccess,
t.TitleId, tj.JournalId
from Titles t
inner join TitleJournals tj on t.TitleId = tj.TitleId
inner join Journals j on j.JournalId = tj.JournalId
inner join Papers p on p.TitleId = t.TitleId
left outer join PaperKeywords pk on pk.PaperId = p.PaperId
left outer join Keywords k on k.KeywordId = pk.KeywordId
left outer join Authors a on a.PaperId = p.PaperId
left outer join Persons ps on ps.PersonId = a.PersonId
left outer join PaperDocs docs on p.PaperId = docs.OuterId and docs.IsCurrent = 1
left outer join PaperPdfs pdfs on p.PaperId = pdfs.OuterId and pdfs.IsCurrent = 1
where 
(CONTAINS(p.name, @title) OR @title = '""')
and ((CONTAINS(docs.*, @body) OR CONTAINS(pdfs.*, @body)) OR @body ='""')
and (CONTAINS(k.*, @keywords) OR @keywords ='""')
and (CONTAINS(ps.*, @authors) OR @authors ='""')
and (t.datum >= @datum OR @datum IS NULL)
and (j.kurzel = @kurzel OR @kurzel IS NULL)
and t.ePub = 1)
20 янв 12, 14:46    [11939815]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
DECLARE @dd= varchar(1000)

SET  @dd = (CASE WHEN @title = '""' THEN 'select * from papers' ELSE  'select * from papers p where CONTAINS (p.name, '+''''+@title+''''+')' END)

exec @dd


или


IF  @title = '""' 
     select * from papers p 
     ELSE 
      select * from papers p where CONTAINS(p.name, @title)



ток в случае с кейсом скорее придется динамический SQL
20 янв 12, 14:53    [11939894]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
amakhin
alexeyvg,

вот исходный запрос, переписывать с UNION или IF достаточно непросто.


UNION нормано будет - даже не смотря на то что запрос вырастет в 6 раз по объему кода, но работать будет лучше.
20 янв 12, 14:59    [11939962]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
denis2710
Member

Откуда: Москва
Сообщений: 3384
Да по любому этот запрос надо переписывать.
Оптимизатор явно не сможет все возможные варианты перебрать и выбрать оптимальный с таким количеством соединений.
Динамический sql лучше не использовать,поддерживать не очень удобно,ну или хотя бы sp_executesql использовать.
IF более предпочтительней
20 янв 12, 15:01    [11939984]     Ответить | Цитировать Сообщить модератору
 Re: Неправильный план в простейшем запросе  [new]
SanyL
Member

Откуда: Москва
Сообщений: 4540
SanyL
amakhin
alexeyvg,

вот исходный запрос, переписывать с UNION или IF достаточно непросто.


UNION нормано будет - даже не смотря на то что запрос вырастет в 6 раз по объему кода, но работать будет лучше.


вернее обычно такой подход помогает сильно - но ситуацию надо смотреть каждый раз отдельно
20 янв 12, 15:01    [11939986]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить