powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
9 сообщений из 9, страница 1 из 1
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011819
valv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
таблица содержит вычисляемое поле [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
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011821
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А если так ?


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


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


а смысл? EquipmentId это идентификатор, не связан с вычисляемым полем; имеет тип int.
в любом случае, не помогло.
...
Рейтинг: 0 / 0
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011828
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
...
Рейтинг: 0 / 0
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011831
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
valv
msLex
А если так ?


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



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

Опс, я подумал EquipmentId и есть вычисляемое поле.
...
Рейтинг: 0 / 0
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011836
valv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011841
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


Любое изменение окружения, ведущее к возможности несовпадения результата вычисления функции с хранимым значением, будет давать такой эффект.
...
Рейтинг: 0 / 0
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011851
valv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
почему вычисляемое поле , объявленное как persisted, пересчитывается при каждом селекте?
    #40011858
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
valv
в том случае, если окружение не меняется.
Это требует проверки.
Вытаскиваете из кеша все планы правильных и неправильных запросов, либо собираете актуальные планы.
Затем с помощью sys.dm_exec_plan_attributes или в самом плане смотрите set options с которыми он был скомпилирован.

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


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