Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте? / 9 сообщений из 9, страница 1 из 1
26.10.2020, 11:46
    #40011819
valv
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
таблица содержит вычисляемое поле [IsArterialShunt]. поле persisted и deterministic.
для вычисления использутся скалярная фунция со schemabinding.


часть селектов читают значение [IsArterialShunt] как и положено, из таблицы, без вызова функции.
например:
Код: sql
1.
 select * from Medical.Equipments


а часть селектов вызывают функцию
например:
Код: sql
1.
2.
 select * from Medical.Equipments 
 where EquipmentId = 1



как заставить второй запрос работать нормально?
он не должен вызывать фунцию.

test:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
create schema Medical
go
CREATE FUNCTION Medical.IsArterialShunt
(
	@SpecShuntId int, @StandardShuntId int
)
RETURNS bit
with schemabinding
AS
BEGIN
  return
  (
    case when @SpecShuntId in (15,16,17,18,19,20,21,22,23,24,25,36,37,38,39)
      or @SpecShuntId is null and @StandardShuntId in (15,16,17,18,19,20,21,22,23,24,25,36,37,38,39)
	then 1 else 0 end
  )
END
GO
drop table Medical.Equipments
go
 create table Medical.Equipments
 (
	EquipmentId int primary key,
	SpecShuntTypeId smallint,
	StandardShuntTypeId smallint,
	IsArterialShunt  AS (isnull(Medical.IsArterialShunt(SpecShuntTypeId,StandardShuntTypeId),(0))) PERSISTED NOT NULL
 )

 insert into Medical.Equipments values (1,2,3)
 go

 -- sample 1: read persisted value
 select * from Medical.Equipments

 -- sample 1: call UDF
 select * from Medical.Equipments 
 where EquipmentId = 1



@@version
Microsoft SQL Server 2016 (SP2-CU15)
Microsoft SQL Server 2019 (RTM) - 15.0.2000.5 (X64)

* это упрощенный пример. в реальности, используются очень тяжелые функции, вызов которых убивает производительность сервера.
...
Рейтинг: 0 / 0
26.10.2020, 11:49
    #40011821
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
А если так ?


Код: sql
1.
2.
select * from Medical.Equipments 
 where EquipmentId = cast(1 as bit)
...
Рейтинг: 0 / 0
26.10.2020, 11:54
    #40011823
valv
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
msLex
А если так ?


Код: sql
1.
2.
select * from Medical.Equipments 
 where EquipmentId = cast(1 as bit)


а смысл? EquipmentId это идентификатор, не связан с вычисляемым полем; имеет тип int.
в любом случае, не помогло.
...
Рейтинг: 0 / 0
26.10.2020, 12:00
    #40011828
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create function dbo.fnTest
(
 @value int
)
returns int
with schemabinding
as
begin
 return @value * 2;
end;
go

create table dbo.t
(
 id int, v int, v2 as dbo.fnTest(v) persisted
);
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

set quoted_identifier off;
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

drop table dbo.t;
drop function dbo.fnTest;
go
...
Рейтинг: 0 / 0
26.10.2020, 12:06
    #40011831
msLex
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
valv
msLex
А если так ?


Код: sql
1.
2.
select * from Medical.Equipments 
 where EquipmentId = cast(1 as bit)



а смысл? EquipmentId это идентификатор, не связан с вычисляемым полем; имеет тип int.
в любом случае, не помогло.

Опс, я подумал EquipmentId и есть вычисляемое поле.
...
Рейтинг: 0 / 0
26.10.2020, 12:15
    #40011836
valv
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
invm
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create function dbo.fnTest
(
 @value int
)
returns int
with schemabinding
as
begin
 return @value * 2;
end;
go

create table dbo.t
(
 id int, v int, v2 as dbo.fnTest(v) persisted
);
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

set quoted_identifier off;
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

drop table dbo.t;
drop function dbo.fnTest;
go


можно ещё 100500 примеров привести, когда persisted столбец работает правильно и не пересчитывается.
вопрос не в этом.
вопрос:
чем причина что он пересчитывается? и как заставить его работать всегда правильно?
...
Рейтинг: 0 / 0
26.10.2020, 12:24
    #40011841
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
valv
чем причина что он пересчитывается? и как заставить его работать всегда правильно?
Т.е. в приведенном примере вы причину не заметили. Может вы вообще его не запускали?

Ок, подсказываю:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create function dbo.fnTest
(
 @value int
)
returns int
with schemabinding
as
begin
 return @value * 2;
end;
go

create table dbo.t
(
 id int, v int, v2 as dbo.fnTest(v) persisted
);
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

set quoted_identifier off;
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

drop table dbo.t;
drop function dbo.fnTest;
go


Любое изменение окружения, ведущее к возможности несовпадения результата вычисления функции с хранимым значением, будет давать такой эффект.
...
Рейтинг: 0 / 0
26.10.2020, 12:56
    #40011851
valv
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
invm
valv
чем причина что он пересчитывается? и как заставить его работать всегда правильно?
Т.е. в приведенном примере вы причину не заметили. Может вы вообще его не запускали?

Ок, подсказываю:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create function dbo.fnTest
(
 @value int
)
returns int
with schemabinding
as
begin
 return @value * 2;
end;
go

create table dbo.t
(
 id int, v int, v2 as dbo.fnTest(v) persisted
);
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

set quoted_identifier off;
go

set statistics xml on;
select * from dbo.t;
set statistics xml off;
go

drop table dbo.t;
drop function dbo.fnTest;
go



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


теперь понял ваш посыл.

уточню вопрос:
в том случае, если окружение не меняется.

как в моём примере, когда запросы идут один за другим,
или в теле одной хранимой процедуры,
без малейшего изменения окружения.
возможно ли заставить persisted поле работать без пересчёта?
если да, то как?
...
Рейтинг: 0 / 0
26.10.2020, 13:23
    #40011858
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
valv
в том случае, если окружение не меняется.
Это требует проверки.
Вытаскиваете из кеша все планы правильных и неправильных запросов, либо собираете актуальные планы.
Затем с помощью sys.dm_exec_plan_attributes или в самом плане смотрите set options с которыми он был скомпилирован.

ЗЫ: Возможно есть другие причины такого поведения, но мне они не известны.
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте? / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]