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

Откуда:
Сообщений: 13147
для секционированных представлений есть ограничения на присутствие индексированных вычисляемых полей. нелогично, но документировано. пусть. но почему это распространяется и на PERSISTED поля? они же вроде как хранятся в таблице?

PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table

это недоработка "в консерватории" и срочно бежать на коннект, просить или я чего таки не понимаю?
3 фев 12, 13:26    [12026014]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
законнектил :)
https://connect.microsoft.com/SQLServer/feedback/details/722968/support-persisted-columns-index-for-partitioned-view
3 фев 12, 15:02    [12027188]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
CREATE VIEW (секция Замечания / Секционированные представления)

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

Добавьте:
+ Details
USE tempdb
GO
CREATE TABLE [dbo].[Test1] (
	 ID	Int	IDENTITY (1,1)
	 CONSTRAINT [PK_Test1] PRIMARY KEY
	 CONSTRAINT [CK_Test1] CHECK (ID < 1000000)
	,[Created]	DateTime	NOT NULL
	 CONSTRAINT [DF_Test1_Created] DEFAULT (GetDate())
--	,[Date]		AS (Convert(Date,[Created])) PERSISTED
)
GO
CREATE TABLE [dbo].[Test2] (
	 ID	Int	IDENTITY (1000000,1)
	 CONSTRAINT [PK_Test2] PRIMARY KEY
	 CONSTRAINT [CK_Test2] CHECK (ID >= 1000000)
	,[Created]	DateTime	NOT NULL
	 CONSTRAINT [DF_Test2_Created] DEFAULT (GetDate())
--	,[Date]		AS (Convert(Date,[Created])) PERSISTED
)
GO
CREATE VIEW [dbo].[vwTest] WITH SCHEMABINDING AS
	SELECT	 ID
		,[Created]
--		,[Date]
	FROM	dbo.Test1
UNION ALL
	SELECT	 ID
		,[Created]
--		,[Date]
	FROM	dbo.Test2
GO
INSERT	dbo.Test1 DEFAULT VALUES
INSERT	dbo.Test2 DEFAULT VALUES

SELECT * FROM dbo.vwTest

UPDATE	dbo.vwTest
SET	[Created] = DateAdd(Month,1,[Created])
WHERE	ID = 1

SELECT * FROM dbo.vwTest
GO
DROP VIEW  dbo.vwTest
DROP TABLE dbo.Test2
DROP TABLE dbo.Test1
Выполнить с откоментированными полями [Date] (в самой VIEW не обязательно).

Msg 4406, Level 16, State 1, Line 6
Ошибка обновления, или вставки представления или функции "dbo.vwTest" из-за отсутствия производного или постоянного поля.
3 фев 12, 16:39    [12028530]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Чёрд.
Mnior
Вычислемые нельзя видимо потому, что нельзя что-то гарантировать. Т.е. может быть что вычисления дают разный результат (типа разные настройки для таблиц/их колонок или баз) или нелзя иметь одно общее состояние переменных окружения влияющие на вычисления
3 фев 12, 16:41    [12028550]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Блин. И без PERSISTED ошибка.

BOL
Указание PERSISTED для вычисляемого столбца позволяет создать индекс по вычисляемому столбцу, который будет детерминистическим, но неточным.
Если смотреть планы, то этот столбец всегда вычисляется:
SET SHOWPLAN_TEXT ON
GO
SELECT * FROM dbo.vwTest
  |--Concatenation
|--Compute Scalar(DEFINE:([tempdb].[dbo].[Test1].[Date]=[tempdb].[dbo].[Test1].[Date]))
| |--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test1].[PK_Test1]))
|--Compute Scalar(DEFINE:([tempdb].[dbo].[Test2].[Date]=[tempdb].[dbo].[Test2].[Date]))
|--Clustered Index Scan(OBJECT:([tempdb].[dbo].[Test2].[PK_Test2]))
3 фев 12, 16:54    [12028686]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
законнектил :)
https://connect.microsoft.com/SQLServer/feedback/details/722968/support-persisted-columns-index-for-partitioned-view
Зря поспешили. А отозвать кажись нельзя. Можно заминусовать и коммент поставить.
3 фев 12, 16:56    [12028703]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
Mnior
Если смотреть планы, то этот столбец всегда вычисляется


верю, но на заборе в MSDN написано:

BOL
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table


вся надежда была на это
3 фев 12, 17:27    [12029000]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
BOL
PERSISTED
Specifies that the SQL Server Database Engine will physically store the computed values in the table
BOL
Marking a computed column as PERSISTED lets you create an index on a computed column that is deterministic, but not precise.

Мда, на основе сказаного (храниться) делается неявный вывод (не вычисляется). Хотя в другом выражении (неточно) можно сделать противоположный вывод.

Или попросить уточнить BOL (в CREATE VIEW) или закрыть Suggestion как ошибочный. А то по свински как-то получится.
Мене закоментить? Просто у меня с буржуйским не ахти.
3 фев 12, 17:52    [12029213]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
от активности вреда не будет. все ошибаются. собственно откуда вопрос - PERSISTED похоже было сделано закрыть определенные вопросы с "настоящим" секционированием. а про представления "забыли" или депрекейтят втихую, что вряд ли, но возможно. вряд ли ибо есть еще "федеративность", которую вряд ли закроют - очень жирный кусок для маркетинга
3 фев 12, 18:13    [12029361]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Думаю лучше переделать вопрос в более конструктивный. Вам ведь явно нужно этот PERSISTED.
Поэтому стоит попросить чтоб он был не просто Deterministic, но и точный, хотябы для некоторых случаев.

Ведь точность, если я не путаю только из-за некоторых видов преобразований или случаев. Точнне из-за состояния переменных окружения (ANSI NULLS и т.п.)

Вот в моём примере преобразование чистое. Тут то можно было прямиком-то как есть колонку выдавать без повторного подсчёта. Плюс это было выгодно для всех кто использует PERSISTED, независмо от секционированных представлений.
3 фев 12, 20:06    [12030002]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
ну, само по себе persisted вроде как и работает:

-- SET QUOTED_IDENTIFIER ON

-- drop table dbo.t1
-- create table dbo.t1 ( id int , status as ( id % 2 ) )

-- drop table dbo.t2
-- create table dbo.t2 ( id int , status as ( id % 2 ) persisted )

-- insert into dbo.t1 ( id ) select id from dbo.sysobjects
-- insert into dbo.t2 ( id ) select id from dbo.sysobjects

set showplan_text on
go
select * from dbo.t1 where status = 1
go
select * from dbo.t2 where status = 1
go
set showplan_text off
go


  |--Compute Scalar(DEFINE:([tempdb].[dbo].[t1].[status]=[tempdb].[dbo].[t1].[status]))
       |--Compute Scalar(DEFINE:([tempdb].[dbo].[t1].[status]=[tempdb].[dbo].[t1].[id]%(2)))
            |--Table Scan(OBJECT:([tempdb].[dbo].[t1]), WHERE:([tempdb].[dbo].[t1].[id]%(2)=CONVERT_IMPLICIT(int,[@1],0)))

  |--Compute Scalar(DEFINE:([tempdb].[dbo].[t2].[status]=[tempdb].[dbo].[t2].[status]))
       |--Table Scan(OBJECT:([tempdb].[dbo].[t2]), WHERE:([tempdb].[dbo].[t2].[status]=CONVERT_IMPLICIT(int,[@1],0)))


вопрос почему на него распространяются ограничения для секционированных представлений - это же "обычное" поле
3 фев 12, 21:01    [12030258]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
дополнительно. и на вычитку тоже все вполне неплохо:

create table dbo.a1 ( c int not null check( c = 1 ) , id int not null , primary key ( id , c ) , status as ( id % 2 ) persisted )
create index ia1_1 on dbo.a1( status )

create table dbo.a2 ( c int not null check( c = 2 ) , id int not null , primary key ( id , c ) , status as ( id % 2 ) persisted )
create index ia2_1 on dbo.a2( status )

create view dbo.v1 with VIEW_METADATA as
select c , id from dbo.a1
union all
select c , id from dbo.a2

insert into dbo.a1 ( c, id ) select 1, id from sysobjects

insert into dbo.a2 ( c, id ) select 2, id from sysobjects

select top 100 * from dbo.v1 where id % 2 = 1


индекс прекрасно работает:

  |--Top(TOP EXPRESSION:((100)))
       |--Concatenation
            |--Index Seek(OBJECT:([tempdb].[dbo].[a1].[ia1_1]), SEEK:([tempdb].[dbo].[a1].[status]=(1)) ORDERED FORWARD)
            |--Index Seek(OBJECT:([tempdb].[dbo].[a2].[ia2_1]), SEEK:([tempdb].[dbo].[a2].[status]=(1)) ORDERED FORWARD)


я к чему веду - для "стабильных" вычисляемых полей (а такие бывают де-факто) чтобы не менять дизайн системы очень удобно добавить вычисляемое + индекс - оптимизатор это понимает. одна беда - представление при этом не может быть изменено
3 фев 12, 21:19    [12030314]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
ну, само по себе persisted вроде как и работает

  |--Compute Scalar(DEFINE:([tempdb].[dbo].[t1].[status]=[tempdb].[dbo].[t1].[status]))
|--Compute Scalar(DEFINE:([tempdb].[dbo].[t1].[status]=[tempdb].[dbo].[t1].[id]%(2)))
|--Table Scan(OBJECT:([tempdb].[dbo].[t1]), WHERE:([tempdb].[dbo].[t1].[id]%(2)=CONVERT_IMPLICIT(int,[@1],0)))

|--Compute Scalar(DEFINE:([tempdb].[dbo].[t2].[status]=[tempdb].[dbo].[t2].[status]))
|--Table Scan(OBJECT:([tempdb].[dbo].[t2]), WHERE:([tempdb].[dbo].[t2].[status]=CONVERT_IMPLICIT(int,[@1],0)))
Ха, в том-то и дело, что обязательное наличие Compute Scalar зашито. А коль так, то оптимизатору приходится писать банальности A = A. Но если будет вариант когда делается неточное вычисления, то сначало будет Prdicate в Seek/Scan, потом Compute Scalar (не просто А = А, а именно вычисление) и опять Filter но уже на "уточнённых" данных. Другое вроде как не получается. Перемудрили.

А вообще первый план явно косячный.

Буэ. Неделя скульного поноса.
3 фев 12, 21:24    [12030331]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
> А вообще первый план явно косячный.

с чего бы это?
3 фев 12, 21:26    [12030338]     Ответить | Цитировать Сообщить модератору
 Re: секционированные представления + PERSISTED вычисляемые поля - просто забыли?  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
> А вообще первый план явно косячный.
с чего бы это?
Минимум 2 раза вычисляется [id]%(2) (в Table Scan + Compute Scalar). План то это практически отображение реальных действий. Лишний Compute Scalar просто так не отображается. Хотя лучше смотреть XML/графический план. Там точнее пишется что там вычисляется и где.
4 фев 12, 02:50    [12031471]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить