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

Откуда:
Сообщений: 776
SQL Server 2005 - 9.00.4912.00 (Intel X86)

Оптимизатор не очень любит сложные запросы и нужно избегать даже вероятности переполнения в запросе. Хотя некоторым простым вещам оптимизатор, видимо, обучен. Поведение для программиста очень неудобное. Уж лучше- всегда получать ошибку, чем нарваться из-за незнания внутренностей оптимизатора. Ниже пример.

Вью используется в запросах.
create view Sequence0 AS
SELECT Id0= n1000.Id* 1000+ n100.Id* 100+ n10.Id* 10+ n1.Id FROM
( SELECT Id= 0 UNION all SELECT 1 UNION all SELECT 2 UNION all SELECT 3 UNION all SELECT 4 UNION all SELECT 5 UNION all SELECT 6 UNION all SELECT 7 UNION all SELECT 8 UNION all SELECT 9 ) n1000,
( SELECT Id= 0 UNION all SELECT 1 UNION all SELECT 2 UNION all SELECT 3 UNION all SELECT 4 UNION all SELECT 5 UNION all SELECT 6 UNION all SELECT 7 UNION all SELECT 8 UNION all SELECT 9 ) n100,
( SELECT Id= 0 UNION all SELECT 1 UNION all SELECT 2 UNION all SELECT 3 UNION all SELECT 4 UNION all SELECT 5 UNION all SELECT 6 UNION all SELECT 7 UNION all SELECT 8 UNION all SELECT 9 ) n10,
( SELECT Id= 0 UNION all SELECT 1 UNION all SELECT 2 UNION all SELECT 3 UNION all SELECT 4 UNION all SELECT 5 UNION all SELECT 6 UNION all SELECT 7 UNION all SELECT 8 UNION all SELECT 9 ) n1

С вью оптимизатору сложнее- получаем ошибки
select * from sequence0 where
dateadd(yy,Id0,'20080101')<='20110101' --Msg 517 overflow
and
Id0<10
----------
select * from sequence0 where
Id0<10
and
dateadd(yy,Id0,'20080101')<='20110101'
----------
select * from (select * from sequence0 where Id0<10) t where
dateadd(yy,Id0,'20080101')<='20110101' --Msg 517 overflow

С временной таблицей проще- ошибок нет
select * into #sequence0 from sequence0
----------
select * from #sequence0 where
dateadd(yy,Id0,'20080101')<='20110101'
and
Id0<10
----------
select * from #sequence0 where
Id0<10
and
dateadd(yy,Id0,'20080101')<='20110101'
----------
select * from (select * from #sequence0 where Id0<10) t where
dateadd(yy,Id0,'20080101')<='20110101'
----------
drop table #sequence0

PS На 2008 сервере поведение аналогичное
12 авг 11, 18:43    [11112248]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор vs возможное переполнение в запросе  [new]
invm
Member

Откуда: Москва
Сообщений: 9833
Ну вот спрашивается, зачем насиловать сервер? Создайте себе постоянную таблицу с числами и будет вам счастье.
12 авг 11, 19:21    [11112392]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор vs возможное переполнение в запросе  [new]
сложные запросы
Guest
автор
Оптимизатор не очень любит сложные запросы и нужно избегать даже вероятности переполнения в запросе.

избегать нужно всегда, сложность запроса тут не причем.

автор
Хотя некоторым простым вещам оптимизатор, видимо, обучен.

Срать оптимизатору на возможное переполнение типа, об этом должен заботиться программист.
В вашем конкретном случае оптимизатор считает, что так просто выгоднее выполнять запрос
12 авг 11, 19:26    [11112407]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор vs возможное переполнение в запросе  [new]
iljy
Member

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

все вопросы легко снимаются взглядом на план. Вьюха оптимизируется целиком, соответственно оптимизатор объединяет вычисление выражений и одновременно вычисляет и число, и дату, до проверки, и тут влетает на переполнение. А при выборке из таблицы проверка осуществляется непосредственно в операторе Table Scan, и большие значения просто до вычислений даты не доходят. Вот и все. Ни о каких переполнениях оптимизатор естественно не думает, да и не может думать - откуда ему знать, чего там у вас за значения в данных?
12 авг 11, 19:51    [11112492]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор vs возможное переполнение в запросе  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 35384
Блог
Ужасно.
1) Если уж не хотите создать свою справочную таблицу, то можно использовать spt_values.
2) После where нельзя писать условия в таком виде, т.к. убивается возможость использования индексов
12 авг 11, 22:15    [11113040]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор vs возможное переполнение в запросе  [new]
SamMan
Member

Откуда: Moscow
Сообщений: 759
Можно резюмировать одной фразой: обеспечение "влезаемости" итогового резалта работы оператора/функции в целевой тип этого оператора/функции - задача только и исключительно программера. Задача движка рапортовать "хозяин! не лезет... :(". Если набор возможных входных значений достигает экстремумов - берите более старший тип.
К оптимизатору вопрос не относится вовсе. Чистый программинг, или даже скорее дизайнинг.
13 авг 11, 13:18    [11114062]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить