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

Откуда:
Сообщений: 241
Добрый день, подскажите, пожалуйста, как можно (1) понять, (2) обойти поведение сервера?

Есть несложный запрос

      select
        *
      from (
        select
          cast(p as bigint)
        from
          (values ('2*2'),('4'))p(p)
        where
          patindex('%[^0-9]%',p)=0
        ) p(p)

он возвращает нам одну строку, со значением p=4. Добавим сюда дополнительное условие p/1 = 4 :

      select
        *
      from (
        select
          cast(p as bigint)
        from
          (values ('2*2'),('4'))p(p)
        where
          patindex('%[^0-9]%',p)=0
        ) p(p)
      where
        p/1 = 4

Что должен возвращать такой запрос по логике вещей? То же самое, одну строку со значением p=4. Ан, нет: второй запрос вообще не отрабатывает, возникает ошибка

Msg 8114, Level 16, State 5, Line 1
Error converting data type varchar to bigint.

Насколько я вижу из плана, к ошибке приводит решение оптимизатора вычислять условие patindex('%[^0-9]%',p)=0 ("p есть число") одновременно с условием p/1 = 4 без какой-либо мысли о том, что проверка второго условия может быть невыполнима для строк, не отвечающих первому. Вопрос к знатокам: это случайность или норма, т.е. оптимизатор действительно не умеет оставаться в пределах здравого смысла, если не может гарантировать, что параллельная проверка переносимых им с этапа на этап условий возможна? По человеческой логике, если не знаешь броду, то не суйся. А по логике оптимизатора? Он большой оптимист?
5 ноя 12, 19:31    [13423377]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Shlippenbaranus
Вопрос к знатокам: это случайность или норма?
Это норма. Сервер считает, что он вправе выполнять разные части запроса в произвольном порядке ради максимальной скорости.
Обычно это обходят с помощью CASE, в котором порядок условий WHEN сервер менять не может.

PATINDEX я, всё-таки, заменил бы на NOT LIKE. Хотя в данном случае не принципиально.
5 ноя 12, 19:47    [13423437]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SirMix
Member

Откуда: Киев
Сообщений: 79
Shlippenbaranus,

насколько я понимаю, то сиквел не может распарсить строку '2*2' как целочисленный тип... это символьная строка а не умножение (если я ничего не путаю) - если заменить это на любое целочисленное значение (к примеру 20), то все выполнится без проблем...

SELECT
	*
FROM
	(
		SELECT
			CAST(p AS BIGINT)
		FROM
			(VALUES ('20'),('4'))p(p)
		WHERE
			PATINDEX('%[^0-9]%',p)=0
	) p(p)
WHERE
	p/1 = 4
5 ноя 12, 19:50    [13423449]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
iap
Shlippenbaranus
Вопрос к знатокам: это случайность или норма?
Это норма. Сервер считает, что он вправе выполнять разные части запроса в произвольном порядке ради максимальной скорости.
Обычно это обходят с помощью CASE, в котором порядок условий WHEN сервер менять не может.

PATINDEX я, всё-таки, заменил бы на NOT LIKE. Хотя в данном случае не принципиально.


Спасибо за ответ. Про case я догадался - запрос вида
        select
          cast(p as bigint)
        from
          (values ('2*2'),('4'))p(p)
        where
          case when isnumeric(p)=1 then p/1 end = 4
работает, - но... как-то это некрасиво. Неочевидно, в частности, могу ли я надеяться, что вычисления, производимые одновременно в select-и where-части запроса (в данном случае cast(p as bigint)) будут всегда выполняться единожды? В чем же здесь фишка - в том, что "второе" условие накладывается на результат вычислений, проведенных над значениями некоторых колонок тех строк, которые были отобраны на основании "первого". Т.е. реально мы имеем что-то вроде
        select
          f(p)
        from
          (values ('2*2'),('4'))p(p)
        where
          case when условие1 then f(p) end = smth
Могу я рассчитывать, что f(p) будет выполняться один раз?

А чем PATINDEX хуже NOT LIKE ?
5 ноя 12, 20:24    [13423574]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
SirMix
Shlippenbaranus,

насколько я понимаю, то сиквел не может распарсить строку '2*2' как целочисленный тип... это символьная строка а не умножение (если я ничего не путаю) - если заменить это на любое целочисленное значение (к примеру 20), то все выполнится без проблем...


Естественно, но тут же в том и смысл - отсеять строки, которые не парсятся в число. А остальные распарсить. В исходных данных есть "плохие" строки, не будь их, вопроса бы не было :).
5 ноя 12, 20:31    [13423588]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Shlippenbaranus
Спасибо за ответ. Про case я догадался - запрос вида
        select
          cast(p as bigint)
        from
          (values ('2*2'),('4'))p(p)
        where
          case when isnumeric(p)=1 then p/1 end = 4
Если и работает, то случайно.
Ничто не мешает серверу сначала выполнить запрос без WHERE, а потом проверять условие.
Это во-первых.
А во-вторых, почему Вы решили, что ISNUMERIC()=1 гарантирует корректное преобразование строки в BIGINT?
Это вовсе не так.

Поэтому CASE надо писать и в SELECTе.
А проверка на конвертируемость в BIGINT сложнее:
CAST
 (
  CASE
   WHEN ISNUMERIC(p)=1
    AND p NOT LIKE '%[^0-9 +-]%'
    AND LEN(REPLACE(REPLACE(REPLACE(p,' ',''),'-',''),'+',''))<=19
   THEN CASE WHEN CAST(p AS DEC(20,0)) BETWEEN -9223372036854775808 AND 9223372036854775807 THEN p END
  END AS BIGINT
 )
Как-то так
5 ноя 12, 21:23    [13423701]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
Shlippenbaranus
Вопрос к знатокам: это случайность или норма, т.е. оптимизатор действительно не умеет оставаться в пределах здравого смысла, если не может гарантировать, что параллельная проверка переносимых им с этапа на этап условий возможна? По человеческой логике, если не знаешь броду, то не суйся. А по логике оптимизатора? Он большой оптимист?

Т.е. из этого запроса оптимизатор должен понять, что вы собрались конвертировать в числа только те строки, которые можно конвертировать ?
А на основании какой части запроса он должен сделать такой вывод ?
6 ноя 12, 10:50    [13424996]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31965
Shlippenbaranus
Неочевидно, в частности, могу ли я надеяться, что вычисления, производимые одновременно в select-и where-части запроса (в данном случае cast(p as bigint)) будут всегда выполняться единожды? В чем же здесь фишка - в том, что "второе" условие накладывается на результат вычислений, проведенных над значениями некоторых колонок тех строк, которые были отобраны на основании "первого"
Почему не оптимальнее проверять первое условие для тех строк, которые отобраны вторым условием???

Если у вас есть условия
WHERE
    условие1 AND
    условие2 AND
    условие3 AND
    условие4

то вполне логично предположить, что они вычисляются в произвольном порядке, в том числе одновременно все или по группам - в зависимости от того, как серверу показалось оптимальнее.

Это естественно, ведь не будет же сервер делать проверки в порядке написания условий, это абсурд.
6 ноя 12, 11:30    [13425246]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
alexeyvg
Почему не оптимальнее проверять первое условие для тех строк, которые отобраны вторым условием???

Если у вас есть условия
WHERE
    условие1 AND
    условие2 AND
    условие3 AND
    условие4

то вполне логично предположить, что они вычисляются в произвольном порядке, в том числе одновременно все или по группам - в зависимости от того, как серверу показалось оптимальнее.

Это естественно, ведь не будет же сервер делать проверки в порядке написания условий, это абсурд.


Почему же абсурд? Есть проверки, которые стоило бы делать именно в порядке написания условий. Т.к. условия бывают разные, в том числе и такие, которые по своему физическому смыслу просто не могут налагаться произвольно.

Как в приведенном мною примере: выполнить проверку p/1=4 перед проверкой patindex('%[^0-9]%',p)=0 может и было бы лучше для быстродействия, но технически не получится. Условия patindex('%[^0-9]%',p)=0 и p/1=4 не коммутативны.

Другое дело, что sql, как язык, не предоставляет возможность указывать приоритеты условий в where-части запроса, и, соотв., возникает вопрос, справедливо поставленный Glory: каким, собственно, образом (в какой части приведенного мною выше запроса) я надеялся определить ту последовательность, в которой должны проверяться условия? Отвечаю: естественным способом определения очереди, в которой должны выполняться ограничивающие выборку условия, мне представлялось использование подзапросов. Поскольку подзапрос - это, считай, вариант cte, а понимать cte просто как синтаксический сахар я не готов. Смотрим источник: A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. Понимаете? С точки зрения логика, это заданный рядом конкретных условий набор, который, в моем изначальном примере, должен бы формироваться с учетом условия "p есть число", но без учета условия p/1=4. Поскольку по синтаксису запроса это второе условие должно быть наложено позже.

При этом, естественно, я не вижу резона оказывать оптимизатору в праве менять порядок вычисления условий, исключая фактическое формирование предполагаемого синтаксисом набора, если данная операция может уменьшить время выполнения запроса и при этом гарантированно безопасна. Но, однако, нашел бы нормальным, если бы оптимизатор умел ограничивать себя в своих усилиях при работе с условиями, коммутативность которых не очевидна.

А он не умеет.

Вот и весь сказ.
6 ноя 12, 19:40    [13428977]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Shlippenbaranus
С точки зрения логика...


Грррр. С точки зрения логикИ.
6 ноя 12, 19:43    [13428982]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
tetxx
Member

Откуда:
Сообщений: 297
iap
А проверка на конвертируемость в BIGINT сложнее
Можно и не сложнее
select isnumeric('2*2')
6 ноя 12, 19:49    [13428998]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
iap
почему Вы решили, что ISNUMERIC()=1 гарантирует корректное преобразование строки в BIGINT?
Это вовсе не так.

В моих условиях гарантирует :). Пример, который я тут привел, понятно, условный, но реальность от него почти не отличается.

iap
Поэтому CASE надо писать и в SELECTе...


Да, спасибо. Так в итоге и вышло.
6 ноя 12, 19:51    [13429005]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
tetxx
iap
А проверка на конвертируемость в BIGINT сложнее
Можно и не сложнее
select isnumeric('2*2')


iap, вероятно, имел в виду защиту от чего-нибудь такого:
select isnumeric('12345678901234567890123456788901234567890')

Т.е. строка может быть конвертируемой в "число", но, например, длиннее, чем укладывается в bigint.
6 ноя 12, 19:56    [13429024]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31965
Shlippenbaranus
alexeyvg
Это естественно, ведь не будет же сервер делать проверки в порядке написания условий, это абсурд.


Почему же абсурд? Есть проверки, которые стоило бы делать именно в порядке написания условий. Т.к. условия бывают разные, в том числе и такие, которые по своему физическому смыслу просто не могут налагаться произвольно.
Стоило бы, но в синтаксисе sql действительно нет возможности такого указания (и не будет, ввиду к стремлению к декларативности языка).

А самостоятельно серверу разобрать зависимости непросто, к тому же это будет сильным ударом по производительности, который получится неконтролируемым (т.е. это просто недопустимо по соображениям совместимости - существующие программы перестанут нормально работать). Так что с этой стороны тоже нельзя ожидать нужного вам поведения даже в будущем.
Shlippenbaranus
А он не умеет.

Вот и весь сказ.
Так что более точно сказать не "не умеет", а разработчики запретили ему такое поведение по причинам, изложенным выше.
6 ноя 12, 20:06    [13429062]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
tetxx
Member

Откуда:
Сообщений: 297
Shlippenbaranus, да, я поспешил с ответом, лишь пробежав тред по диагонали.

Хотя странно. msdn пишет

http://msdn.microsoft.com/ru-ru/library/ms186272.aspx
Функция ISNUMERIC возвращает 1, если при оценке входного выражения получается допустимый числовой тип данных. В противном случае возвращается 0. Ниже приведены допустимые числовые типы данных:
...
bigint
...
Тем не менее, пример с большим числом рабочий и isnumeric=1, хотя cast, конечно же, вываливается с ошибкой. Мда...
6 ноя 12, 20:08    [13429079]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Eщё раз про ISNUMERIC().
Ребята, вы чего?!

Сколько тут тем про это!
Ну вот, например: ошибка при конвертации
6 ноя 12, 21:26    [13429378]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
Eщё раз про ISNUMERIC().
Ребята, вы чего?!

Сколько тут тем про это!
Ну вот, например: ошибка при конвертации
Или вот:преобразовать string в int
Или Допустимость преобразования
6 ноя 12, 21:31    [13429397]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Shlippenbaranus
iap, вероятно, имел в виду защиту от чего-нибудь такого:

Я думаю, что iap, имел ввиду, что надо всегда помнить, что sql - декларативный язык, т.е. мы описываем "что", а не "как". Памятуя об этом, странно рассуждать, что вычисляется вперед чего. Думайте так, что все вычисляется - одновременно.
Но если вы влезаете внутрь (неблагодарное занятие, т.к. может измениться без всякого ведома), то вот вам загадка, почему в одном случае джойнится, а в другом нет:
use tempdb
go
create table dbo.t1 (a int, b varchar(1));
create table dbo.t2 (a int);
go
insert dbo.t1 values(1,'1'),(10,'a');
insert dbo.t2 values(1),(2),(3);
go
select t1.a, convert(int,t1.b) from dbo.t1 join dbo.t2 on t1.a = t2.a;
go
select t1.a, convert(int,t1.b) from dbo.t1 join dbo.t2 on t1.a = t2.a option(loop join);
go
drop table dbo.t1, dbo.t2;

На всякий случай, у меня 2008r2 rtm
6 ноя 12, 23:45    [13429829]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
SomewhereSomehow
если вы влезаете внутрь (неблагодарное занятие, т.к. может измениться без всякого ведома), то вот вам загадка, почему в одном случае джойнится, а в другом нет:
use tempdb
go
create table dbo.t1 (a int, b varchar(1));
create table dbo.t2 (a int);
go
insert dbo.t1 values(1,'1'),(10,'a');
insert dbo.t2 values(1),(2),(3);
go
select t1.a, convert(int,t1.b) from dbo.t1 join dbo.t2 on t1.a = t2.a;
go
select t1.a, convert(int,t1.b) from dbo.t1 join dbo.t2 on t1.a = t2.a option(loop join);
go
drop table dbo.t1, dbo.t2;

Тут понятно: согласно плану первого запроса, он выполняется с применением hash join, т.е. перед началом соединения формируется кеш, в который выгружаются все потенциально участвующие в соединении строки одного из участвующих в соединении наборов, а именно, меньшего. И в данном случае это выборка из t1. Вот в процессе формирования кеша и происходит беда. Как это можэно проверить? Ну, вот по той же самой логике, для того, чтобы избежать появления исключения, не обязательно использовать подсказку loop join . Можно просто заставить движок конструировать кеш на основе t2. И действительно, если мы сделаем так:
...
create table dbo.t1 (a int, b varchar(1));
create table dbo.t2 (a int);
go
insert dbo.t1 values(1,'1'),(2,'2'),(3,'3'),(4,'4'),(10,'a');
insert dbo.t2 values(1);
go
select t1.a, convert(int,t1.b) from dbo.t1 join dbo.t2 on t1.a = t2.a;
...
запрос благополучно отработает.
7 ноя 12, 13:14    [13432490]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
Shlippenbaranus
запрос благополучно отработает.


А план запроса внешне выглядит так же
7 ноя 12, 13:16    [13432505]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Shlippenbaranus,

Если посмотреть на планы, то вы не обратили внимание, на то что оператор compute scalar и там и там указан ДО того как будет выполнено соединение. Если б был указан после - вопросов бы не было.
|--Hash Match(Inner Join, HASH:([tempdb].[dbo].[t1].[a])=([tempdb].[dbo].[t2].[a]), RESIDUAL:([tempdb].[dbo].[t2].[a]=[tempdb].[dbo].[t1].[a]))
   |--Compute Scalar(DEFINE:([Expr1008]=CONVERT(int,[tempdb].[dbo].[t1].[b],0)))
   |    |--Table Scan(OBJECT:([tempdb].[dbo].[t1]))

|--Nested Loops(Inner Join, WHERE:([tempdb].[dbo].[t2].[a]=[tempdb].[dbo].[t1].[a]))
   |--Compute Scalar(DEFINE:([Expr1008]=CONVERT(int,[tempdb].[dbo].[t1].[b],0)))
   |    |--Table Scan(OBJECT:([tempdb].[dbo].[t1]))

Почему тогда в одном случае джойнится а в другом нет?

Оказывается, дело в том, что сиквел сервер имеет такой механизм оптимизации, как отложенное вычисление некоторых выражений. И хотя в плане указан следующий порядок: просканирвоали строки -> преобразовали -> сджойнили. На самом деле: просканировали -> сджойнили -> преобразовали. Такое поведение с 2005 сервера. Это я к тому, что как и когда сервер может выполнять преобразования зависит от того куда помещен оператор convert, когда он реально выполнится, в контексте каких операторов он выполняется, используются ли хинты и т.д. - можно утонуть в деталях. Предпочитаю полагаться на известные конструкции, типа того же кейса, чем помнить все нюансы, когда там что вычисляется.
7 ноя 12, 13:39    [13432749]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
Shlippenbaranus
Member

Откуда:
Сообщений: 241
SomewhereSomehow
Shlippenbaranus,

Если посмотреть на планы, то вы не обратили внимание, на то что оператор compute scalar и там и там указан ДО того как будет выполнено соединение. Если б был указан после - вопросов бы не было.

Да, действительно, не обратил. Может быть, потому, что compute scalar до ограничения выборки "из первых принципов" кажется неоптимальным, причем не только мне, но и серверу, который хоть и объявляет по приколу, что будет компьютить скаляр до выполнения джойна, но в реальности делает правильно. "Если на клетке слона написано 'буйвол', не верь глазам своим" (с).

Если без шуток, ms sql при таком поведении нужно назвать весьма опасным для промышленного применения. Т.к. теперь я должен ожидать, что сложный код, даже будучи протестирован на фактических данных, и даже отработав безупречно в течение долгого времени, может внезапно начать глючить - без каких-либо правок, без изменения в ограничениях, накладываемых на исходные данные ("не формируются строки длиной больше 16 символов", проч.), просто из-за того, что изменятся планы запросов. Ведь не бывает кода без ошибок, совет "пиши сразу правильно", он не работает. А отладка в ms sql получается затруднена. И это реальность, только теперь я понимаю природу безумных ошибок, не воспроизводившихся на тестовых данных, с которыми я мучился около года назад. Тогда я решил, просто сервер шалит, благо он действительно требовал 100% что CPU, что памяти, так что в итоге сервер пришлось поменять. Ан, наверное, дело было в другом.
7 ноя 12, 15:24    [13433694]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Shlippenbaranus
Если без шуток, ms sql при таком поведении нужно назвать весьма опасным для промышленного применения.

Не согласен.

Shlippenbaranus
Т.к. теперь я должен ожидать, что сложный код, даже будучи протестирован на фактических данных, и даже отработав безупречно в течение долгого времени, может внезапно начать глючить - без каких-либо правок, без изменения в ограничениях, накладываемых на исходные данные ("не формируются строки длиной больше 16 символов", проч.), просто из-за того, что изменятся планы запросов.

Нет. Теперь вы должны ожидать, что если раньше что-то работало но не гарантировалось, то с новой версией это также не гарантируется. И даже, если что-то работало гарантировано, то с новой версией - это может не работать, с учетом документированных изменений.
Самое главное - это происходит не внезапно.
Вот документировано:
автор
Sometimes, SQL Server 2005 evaluates expressions in queries sooner than SQL Server 2000. This behavior provides the following important benefits:

Troubleshooting Errors and Warnings on Query Expressions
С другой стороны, я понимаю, что реально, невозможно прочитать, запомнить, понять и сопоставить, абсолютно все нюансы, с абсолютно всеми старыми серверами при переходе. Ну, тут уж нужно как-то вырабатывать общий подход. Следить за деприкейтед фичами, следить за критическими точками. Опять же, соблюдая общие рекомендации МС, вы не наткнетесь на такие вилы (по крайней мере не должны).

Но если вы полагаетесь на некие "продвинутые внутренние знания", которые не документированы, например, знаете какое влияние оказывает хинт force order, то - просто отслеживайте такие места!
И если, внезапно (на самом деле не очень внезапно, ведь вы сами инициируете обновление) что-то недокументированное перестает работать - то пеняйте на себя.
Если перестает работать документированное - то нужно писать в поддержку.
Я не защищаю МС, но имхо, такой подход справедливый.
Именно уменьшением случаев всяческого "внутреннего знания", разработчики МС аргументируют нежелание раскрывать некие детали реализации (даже не ключевые для бизнеса). Дескать - "не будете знать как работает - не будете на это полагаться".
И это правильно, имхо. По этому, я сам, когда говорю о недокументированных вещах, стараюсь подчеркнуть, что это просто для понимания, а не для применения в промышленной эксплуатации.

Сообщение было отредактировано: 9 ноя 12, 01:58
9 ноя 12, 01:22    [13443240]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
SomewhereSomehow,

Прошу прощения, последний абзац остался от копипасты, уважаемым модераторам, просьба поправить для порядка, если критично.
9 ноя 12, 01:24    [13443247]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизатор роняет запрос  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Ошибка устранена, спасибо!
9 ноя 12, 02:16    [13443446]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить