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

Откуда:
Сообщений: 1196
Всем привет!
Есть таблица, участвующая в репликации.
Она заполняется несколькими операторами в одной транзакции, типа такого:
BEGIN TRANSACTION;
	
	WITH CTE AS (SELECT ... FROM Sales WHERE ...)
	MERGE CTE WITH (TABLOCK) AS T
                USING (SELECT ... FROM ) AS S
                ON T.ProductId = S.ProductId AND T.Day = S.Day
	WHEN MATCHED AND (ISNULL(T.Price, 0.0) <> ISNULL(S.Price, 0.0) ...
		THEN UPDATE SET Price = S.Price, ...
	WHEN NOT MATCHED BY TARGET
		THEN INSERT (ProductId, Day, ...)
		VALUES(S.ProductId, S.Day,...)
	WHEN NOT MATCHED BY SOURCE
		THEN DELETE;

	UPDATE Sales WITH (TABLOCK)
	SET Price = ...
        WHERE ...

	UPDATE Sales 
	SET Price = ...
        WHERE ...

	EXEC DW.JumpingPrice

COMMIT TRANSACTION

При этом значения большинства строк в итоге не изменяется. Но все изменения,выполненные в транзакции, реплицируются, что значительно увеличивает траффик.

Каким образом можно реплицировать только итоговые изменения?
Пока есть одна идея: создать таблицу-клон, и через MERGE её обновлять.

Может, кто-нибудь ещё что-то подскажет?
5 фев 13, 17:03    [13879275]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Crimean
Member

Откуда:
Сообщений: 13147
а это случаем не хранимкой делается? можно попробовать пробросить только вызов хранимки
5 фев 13, 17:22    [13879447]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
В смысле репликацию выполнения процедуры?
Проблема: на подписчике нет таблиц-источников.
5 фев 13, 17:24    [13879471]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Crimean
Member

Откуда:
Сообщений: 13147
альтернатива - попробовать добавить в UPDATE строчку WHERE <> чтобы обновлялось только то, что реально изменилось
или уже предложенный вариант через +1 табличку
5 фев 13, 17:45    [13879679]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Избавится от
Jovanny
При этом значения большинства строк в итоге не изменяется
не получится?
5 фев 13, 17:48    [13879694]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Еще можно навесить instead of триггер, которых будет игнорировать холостые изменения.
5 фев 13, 17:58    [13879760]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
invm,

Насчёт триггера интересная идея. Интересно, как это скажется на производительности.
5 фев 13, 18:08    [13879815]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Хотя нет.
Одни и те же строки могут изменяться несколько раз за транзакцию.
Боюсь, что таблица клон - самое оптимальное решение.
5 фев 13, 18:10    [13879825]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Jovanny
Одни и те же строки могут изменяться несколько раз за транзакцию.
Ну можете накапливать изменения во временной таблице и в конце транзакции применять их к основной с контролем холостых обновлений.
5 фев 13, 18:31    [13879904]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
invm,

Спасибо, тоже вариант.
5 фев 13, 18:44    [13879964]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Crimean
Member

Откуда:
Сообщений: 13147
ой, instead of update - может быть очень страшной вещью. особенно, если к таблице применяется более 1 "разномастного" оператора update + на таблице более чем 1 индекс.
5 фев 13, 19:24    [13880171]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Crimean
ой, instead of update - может быть очень страшной вещью. особенно, если к таблице применяется более 1 "разномастного" оператора update + на таблице более чем 1 индекс.
А подробнее можно? Или где почитать?
Имею аналогичную картину на одной из самых нагруженных таблиц и проблем замечено не было.
5 фев 13, 20:53    [13880508]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Crimean
Member

Откуда:
Сообщений: 13147
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, а для остального - оставил "плохой" общий код, который тупо меняет все поля. в результате оверхед существенно сократился
а что бывает с таким триггером, если у нас не таблица, а нечто посложнее.. или там поля секционирования потенциально могут меняться.. ммм...
5 фев 13, 21:02    [13880539]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Crimean
в случае, если, скажем, на Column1 нет индексов, а на Column2 есть индексы - при отсутствии триггера меняет только данные, а при наличии триггера - прицепом тянет и индекс на Column2 ну и дальше по списку
Ну это само собой. Я-то подумал, что нечто деструктивное будет :)
Кстати, на 2008 R2 (на более младших не проверял) холостые модификации столбцов благополучно игнорируются, т.е. никаких лишних обновлений индексов не будет. В журнале это хорошо видно.
5 фев 13, 21:34    [13880661]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
Crimean
Member

Откуда:
Сообщений: 13147
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, конечно же
5 фев 13, 22:04    [13880754]     Ответить | Цитировать Сообщить модератору
 Re: Репликация транзакций - пропустить промежуточные изменения  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
Crimean
если я нигде не напутал ( что ой как бывает ) то мы чудно видим блокировку на индекс 2
Да, именно так.
Ну хоть с таблицами работает, и то хлеб.
5 фев 13, 22:53    [13880951]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить