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

Откуда:
Сообщений: 86
Наверняка не бывает такого, чтобы анализатор не понял этого, но...

Чего-то типа

select (a*b*c+d-e-f) r,
case
when (a*b*c+d-e-f) =0 then 1
when (a*b*c+d-e-f) >30 then 2
when log(a*b*c+d-e-f)<1 then 3
else 0 end
from aaaaaaa
where (a*b*c+d-e-f) >=0

даже не вопрос, чтобы не писать a*b*c+d-e-f каждый раз
а просто чтобы анализатор не сделал план с пятью вычислениями a*b*c+d-e-f

или только

select r,
case
when r=0 then 1
when r>30 then 2
when log(r)<1 then 3
else 0 end
from (
select a*b*c+d-e-f r
from aaaaaaa
)
where r>=0

?

в доке смотрел, так уж спрошу на всякий случай)
9 апр 19, 22:55    [21857780]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6356
dklim.kzn,

математические вычисления - не самое медленное, с чем можно столкнуться на сервере. Например, целочисленное произведение современный процессор выполняет за один такт.
9 апр 19, 23:21    [21857788]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
Наверняка не бывает такого, чтобы анализатор не понял этого, но...
Уверен, что оптимизатор в сиквеле даже не имеет оптимизирующего это блока, за ненадобностью.
Самому, конечно, нужно писать это по методу "или только", не для оптимизации, а для сокращения вероятности ошибок.
9 апр 19, 23:50    [21857798]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
Критик
Member

Откуда: Москва / Калуга
Сообщений: 31392
Блог
dklim.kzn,

Думаю, это бессмысленно, ибо ресурсов жрет тысячные доли процента производительности
10 апр 19, 01:59    [21857840]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
еще и планы одинаковые
ну может на этапе исполнения кэшируется

alexeyvg
dklim.kzn
Наверняка не бывает такого, чтобы анализатор не понял этого, но...
Уверен, что оптимизатор в сиквеле даже не имеет оптимизирующего это блока, за ненадобностью.
Самому, конечно, нужно писать это по методу "или только", не для оптимизации, а для сокращения вероятности ошибок.


что за метод "или только"?
разовьюсь)))
10 апр 19, 08:21    [21857919]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
Посетитель
Member

Откуда:
Сообщений: 1023
dklim.kzn
еще и планы одинаковые
ну может на этапе исполнения кэшируется

alexeyvg
пропущено...
Уверен, что оптимизатор в сиквеле даже не имеет оптимизирующего это блока, за ненадобностью.
Самому, конечно, нужно писать это по методу "или только", не для оптимизации, а для сокращения вероятности ошибок.


что за метод "или только"?
разовьюсь)))


это метод из вашего сообщения
10 апр 19, 08:46    [21857931]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
что за метод "или только"?
разовьюсь)))

dklim.kzn
или только

select r,
case
when r=0 then 1
when r>30 then 2
when log(r)<1 then 3
else 0 end
from (
select a*b*c+d-e-f r
from aaaaaaa
)
where r>=0
10 апр 19, 09:36    [21857963]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
.Евгений
Member

Откуда:
Сообщений: 465
dklim.kzn,

переходите на ассемблер, или хотя бы на C++. Там эта тема будет более актуальна.
10 апр 19, 09:48    [21857985]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
Критик
Думаю, это бессмысленно, ибо ресурсов жрет тысячные доли процента производительности
А вообще, посмотрел, разница заметная :-)

Возьмём такой пример:
select SUM(cast(c.id as float))
from (
	select top 1000000 c1.id 
	from syscolumns c1 
		cross join syscolumns c2
) c
go
select SUM(cast(c.id + c.id/2 + 3 - c.id * 3.14 + c.id as float))
from (
	select top 1000000 c1.id 
	from syscolumns c1 
		cross join syscolumns c2
) c
У меня разница (по CPU и Duration) между запросами стабильно в 2 раза.
Так что, наверное, оптимизация, про которую говорит автор, могла бы ускорить некоторые запросы в несколько раз.
10 апр 19, 11:29    [21858097]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6142
alexeyvg,
автор
У меня разница (по CPU и Duration) между запросами стабильно в 2 раза.

и всё это только приведение типов
10 апр 19, 11:35    [21858103]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
Руслан Дамирович
Member

Откуда: Резиновая нерезиновая
Сообщений: 861
dklim.kzn,
Как правильно написали, просто чтобы исключить ошибки copy-paste можно использовать CROSS APPLY
Не умеет он оптимизировать, он на каждое выражение WHEN создает отдельную переменную, и даже можно дойти до лимита переменных, если использовать несколько последовательных CROSS APPLY с CASE внутри.
SELECT 
  ss1.[r], 
  ss2.[c]
FROM 
  aaaaaaa t
  CROSS APPLY (
    SELECT [r] = t.[a]*t.[b]*t.[c] + t.[d] - t.[e] - t.[f]
  ) ss1
  CROSS APPLY (
    SELECT [c] = CASE 
      WHEN ss1.[r] = 0 THEN 1 
      WHEN ss1.[r] > 30 THEN 2 
      WHEN log( ss1.[r] ) < 1 THEN 3
      ELSE 0
    END
  ) ss2
WHERE
  ss1.[r] >= 0
10 апр 19, 11:55    [21858119]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
TaPaK
alexeyvg,
автор
У меня разница (по CPU и Duration) между запросами стабильно в 2 раза.

и всё это только приведение типов
Да, наверное, некорректный пример...
Вот, попробую так:
select SUM(1 + f1), SUM(2 + f1), SUM(3 + f1)
from (
	select 1 + id1/2 + 3 - id2 * 3.14 + id2 as f1
	from (
		select top 1000000 cast(c1.id as float) as id1, cast(c2.id as float) as id2
		from syscolumns c1 
			cross join syscolumns c2
	) c
) c
go
select SUM(1 + f1), SUM(2 + f2), SUM(3 + f3)
from (
	select 1 + id1/2 + 3 - id2 * 3.14 + id2 as f1, 2 + id1/2 + 3 - id2 * 3.14 + id2 as f2, 3 + id1/2 + 3 - id2 * 3.14 + id2 as f3
	from (
		select top 1000000 cast(c1.id as float) as id1, cast(c2.id as float) as id2
		from syscolumns c1 
			cross join syscolumns c2
	) c
) c
10 апр 19, 14:45    [21858374]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
Посетитель
dklim.kzn
еще и планы одинаковые
ну может на этапе исполнения кэшируется

пропущено...


что за метод "или только"?
разовьюсь)))


это метод из вашего сообщения


)))

И знаете, что делается?
Не работает "или только".
Предикат считается отдельно.
А скаляр отдельно в другом пункте плана.

Я писал, что планы одинаковые в итоге.
Если только какой то оптимизатор дальше роляет.
Кэш процессора или менеджер исполнения какой-нибудь.
11 апр 19, 06:36    [21858886]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
.Евгений
dklim.kzn,

переходите на ассемблер, или хотя бы на C++. Там эта тема будет более актуальна.


Для моей задачи и sql подходит
На i7 время исполнения запооса по таблице с 1м записей то 0 то 1 мс, это годиться.

На С перейти сейчас можно с использованием oltp. Но кстати, пришлось отказаться от использования. Отключает параллелизм, и еще ограничения в запросах - в итоге неOLTP получается быстрее. И я не помню еще, отключается ли batch для колумнстор. В итоге оставил обычный запрос, но с таблицами, оптимизированными для памяти.

Про использование С интересно почитать. А именно в чем смысл от сервера тогда, какой вариант ускорения от С ?

Вообще часто можно ускорить запрос до нужного.
Основной запрос у меня считается только по свежим записям. Но для этого надо получить из последней записи максимаальный номер (не identity). Ключ по двум полям, и номер - второй. Поэтому отлично получилось по TOP брать вязкой с таблицей стационарных значений первого поля в ключе, а потом уже брать максимум из этих значений.
11 апр 19, 07:04    [21858889]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
На С перейти сейчас можно с использованием oltp. Но кстати, пришлось отказаться от использования. Отключает параллелизм, и еще ограничения в запросах - в итоге неOLTP получается быстрее
В смысле? OLTP - это оперативная обработка транзакций. Например, 1С. И вообще большинство БД.
11 апр 19, 10:20    [21859001]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
.Евгений
Member

Откуда:
Сообщений: 465
dklim.kzn
Про использование С интересно почитать. А именно в чем смысл от сервера тогда, какой вариант ускорения от С ?

Не знаю, что вы поняли из моих слов.
Я говорил о том, что СУБД при выполнении sql-запроса нагружает процессоры множеством относительно простых действий (например, чтением страниц памяти, формированием рекордсета, обновлением статистики и т.д.) и некоторым количеством сложных (типа переключения контекста потока). По этой причине ваши пять вычислений - просто экономия на спичках. Если бы ваши 1 млн записей по 50 байт хранились в стандартной коллекции (любого компилируемого ЯВУ), то подобная вашей оптимизация могла ускорить работу с ней.
11 апр 19, 11:23    [21859111]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
alexeyvg
dklim.kzn
На С перейти сейчас можно с использованием oltp. Но кстати, пришлось отказаться от использования. Отключает параллелизм, и еще ограничения в запросах - в итоге неOLTP получается быстрее
В смысле? OLTP - это оперативная обработка транзакций. Например, 1С. И вообще большинство БД.


OLTP-процедуры компилируются "в собственный код", в dll, через промежуточное формирование файлов на С.

Я не сомневаюсь,, что Вам это известно, но просто отмечаю, что если кому-то очень надо в С - велкам ту OLTP-процедуры )))
Толку на самом деле немного лично для меня пока в смысле применения для расчетов - обычные запросы быстрее
Но вот грядет написание триггера, он будет NC, может увижу разницу
11 апр 19, 12:50    [21859271]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
.Евгений,

ну да, похоже сервер не парится с этим
важнее отделить блок фильтрации от блока расчетов
11 апр 19, 12:52    [21859275]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
uaggster
Member

Откуда:
Сообщений: 554
dklim.kzn
Наверняка не бывает такого, чтобы анализатор не понял этого, но...

Чего-то типа

select (a*b*c+d-e-f) r,
case
when (a*b*c+d-e-f) =0 then 1
when (a*b*c+d-e-f) >30 then 2
when log(a*b*c+d-e-f)<1 then 3
else 0 end
from aaaaaaa
where (a*b*c+d-e-f) >=0

в доке смотрел, так уж спрошу на всякий случай)


Легко!

select t.n r, 
case 
when t.n =0 then 1 
when t.n >30 then 2 
when log(t.n)<1 then 3
else 0 end
from aaaaaaa a
	Cross apply(Values (a*b*c+d-e-f)) t(n)
where  t.n >=0


И, кстати:
Владислав Колосов
dklim.kzn,
математические вычисления - не самое медленное, с чем можно столкнуться на сервере. Например, целочисленное произведение современный процессор выполняет за один такт.

Если один из компонентов - скалярка - всё совсем не радужно.
11 апр 19, 13:39    [21859379]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
alexeyvg
В смысле? OLTP - это оперативная обработка транзакций. Например, 1С. И вообще большинство БД.


OLTP-процедуры компилируются "в собственный код", в dll, через промежуточное формирование файлов на С.

Я не сомневаюсь,, что Вам это известно, но просто отмечаю, что если кому-то очень надо в С - велкам ту OLTP-процедуры )))
А, понятно.
Это называется Natively Compiled Stored Procedures.
А OLTP - это OnLine Transaction Processing
11 апр 19, 13:41    [21859384]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
OLTP-процедуры компилируются "в собственный код", в dll, через промежуточное формирование файлов на С.
Интересно, где вам попалась такая интерпретация этой аббревиатуры?
11 апр 19, 13:43    [21859388]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 6356
Да, мне тоже интересно. OLPT не диктует внутреннюю реализацию. Компиляция процедур в пи-код обусловлена использованием механики интерпретатора.
11 апр 19, 13:53    [21859418]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
dklim.kzn
Member

Откуда:
Сообщений: 86
ну у меня так скомпилировалось в собственный код)
мс добивались и добилась желаемого, наверное

впрочем, ничего страшного не вижу
наверное, если ms сделали что-то для чего-то - то можно "внутри мс" говорить и в таком варианте
если мс сделали отдельный вид процедур для использования в oltp-решениях, то ...

а так, конечно, у меня тоже oltp на несколько тысяч транзакций в секунду
и как минимум 3/4 будет пережевываться не nc-процедурой
но при этом в таблице, оптимизированной для памяти

однако, тоже вопрос спорный и пограничный - транзакции ли у меня)))
если расчеты делаются по каждой, но какие-то результаты генерируются только для единиц из них
12 апр 19, 14:40    [21860589]     Ответить | Цитировать Сообщить модератору
 Re: Можно ли анализатору явно указать выражение, которое считать 1 раз, а дальше использовать  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 28168
dklim.kzn
ну у меня так скомпилировалось в собственный код)
мс добивались и добилась желаемого, наверное

впрочем, ничего страшного не вижу
наверное, если ms сделали что-то для чего-то - то можно "внутри мс" говорить и в таком варианте
если мс сделали отдельный вид процедур для использования в oltp-решениях, то ...

а так, конечно, у меня тоже oltp на несколько тысяч транзакций в секунду
и как минимум 3/4 будет пережевываться не nc-процедурой
но при этом в таблице, оптимизированной для памяти

однако, тоже вопрос спорный и пограничный - транзакции ли у меня)))
если расчеты делаются по каждой, но какие-то результаты генерируются только для единиц из них
Жесть
12 апр 19, 21:03    [21860882]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить