Репликация транзакций - пропустить промежуточные изменения

Crimean
Дата: 05.02.2013 19:24:14
ой, instead of update - может быть очень страшной вещью. особенно, если к таблице применяется более 1 "разномастного" оператора update + на таблице более чем 1 индекс.
invm
Дата: 05.02.2013 20:53:09
Crimean
ой, instead of update - может быть очень страшной вещью. особенно, если к таблице применяется более 1 "разномастного" оператора update + на таблице более чем 1 индекс.
А подробнее можно? Или где почитать?
Имею аналогичную картину на одной из самых нагруженных таблиц и проблем замечено не было.
Crimean
Дата: 05.02.2013 21:02:56
invm
А подробнее можно? Или где почитать?
Имею аналогичную картину на одной из самых нагруженных таблиц и проблем замечено не было.


почитать - наврядли. поподробенее - попробую. для instead of update, если все делать "буквально", мы вынуждены писать что-то типа такого в теле триггера:

update a
set a.Column1 = i.Column1, a.Column2 = i.Column2, ...
from Table1 as a
join inserted as i on i.Id = a.Id

где Column* - все поля, кроме ПК, для Table1. теперь безобидный запрос

update Table1 set Column1 = @Value1 where Id = @Id

в случае, если, скажем, на Column1 нет индексов, а на Column2 есть индексы - при отсутствии триггера меняет только данные, а при наличии триггера - прицепом тянет и индекс на Column2 ну и дальше по списку

безусловно, если знать все "типовые update" - можно в триггере их "развести" через if else. но! если типовых update как таковых нет - получаем или серьезный оверхед или необходимость генерить неслабый такой код с if else для перебора всех комбинаций обновляемых полей. я поступил компромиссно - бОльший % таких типовых update покрыл действительно секциями if else, а для остального - оставил "плохой" общий код, который тупо меняет все поля. в результате оверхед существенно сократился
а что бывает с таким триггером, если у нас не таблица, а нечто посложнее.. или там поля секционирования потенциально могут меняться.. ммм...
invm
Дата: 05.02.2013 21:34:42
Crimean
в случае, если, скажем, на Column1 нет индексов, а на Column2 есть индексы - при отсутствии триггера меняет только данные, а при наличии триггера - прицепом тянет и индекс на Column2 ну и дальше по списку
Ну это само собой. Я-то подумал, что нечто деструктивное будет :)
Кстати, на 2008 R2 (на более младших не проверял) холостые модификации столбцов благополучно игнорируются, т.е. никаких лишних обновлений индексов не будет. В журнале это хорошо видно.
Crimean
Дата: 05.02.2013 22:04:02
invm,

хехе. оно-то в простом случае - да. но не в сложном

use tempdb 
go

create table dbo.a1 ( id int primary key , f1 int not null , f2 int not null , check ( id = 1 ))
create table dbo.a2 ( id int primary key , f1 int not null , f2 int not null , check ( id = 2 ))
create table dbo.a3 ( id int primary key , f1 int not null , f2 int not null , check ( id = 3 ))
go

create index I_a1_f1 on dbo.a1( f1 )
go
create index I_a2_f1 on dbo.a2( f1 )
go
create index I_a3_f1 on dbo.a3( f1 )
go

create view dbo.v1 as select * from dbo.a1 union all select * from dbo.a2 union all select * from dbo.a3
go

insert into dbo.v1( id , f1, f2 ) select 1, 1, 1 union all select 2, 2, 2 union all select 3, 3, 3
go

create trigger dbo.t_v1_1 on dbo.v1 instead of update as 
set nocount on

update v
set v.f1 = i.f1, v.f2 = i.f2
from dbo.v1 v
join inserted i on i.id = v.id

return
go

begin tran

update dbo.v1 set f2 = f2 * 10 where id = 2

exec sp_lock @@spid

rollback
go

if @@trancount <> 0 rollback
go

drop view dbo.v1
go
drop table dbo.a1
go
drop table dbo.a2
go
drop table dbo.a3
go


если я нигде не напутал ( что ой как бывает ) то мы чудно видим блокировку на индекс 2
чего, конечно же, не будет, если не мутить "апдейтабл партишенед вью"
подозреваю, это не единственное "исключение из правил"
да, все на R2, конечно же
invm
Дата: 05.02.2013 22:53:19
Crimean
если я нигде не напутал ( что ой как бывает ) то мы чудно видим блокировку на индекс 2
Да, именно так.
Ну хоть с таблицами работает, и то хлеб.