In a post about how update works I showed what happened when run an update with the same values. SQL Server is smart enough to see that and not changing anything and register minimum log.
Another day I saw a comment to avoid updating records when none of the values are changing.
Avoid updating records when none of the values are changing. This still does a write and, if the table is in replication or change tracking, still causes the row to be propagated out to other servers. If you are updating a potentially large number of records, make sure to only update the ones where the new value doesn’t equal the old value.
Let’s see how the update behavior when update 10 millions rows but without any change and see if will be any row propagation to another server.
My Lab contains two servers and a demo database replicated from SQL01 to SQL02.
It’s configured a transaction replication to send the articles and I’m using a table created with the code:
CREATE TABLE tblMillionsRows ( id BIGINT NOT NULL IDENTITY PRIMARY KEY, largeColumn NVARCHAR(MAX) DEFAULT REPLICATE('TESTE',100), smallColumn NVARCHAR(150) DEFAULT 'DEMO', dateColumn DATETIME DEFAULT GETDATE() ); GO
INSERT INTO dbo.tblMillionsRows ( largeColumn, smallColumn, dateColumn ) DEFAULT VALUES GO 2000000
It will take a while to insert all rows. The next step is add this table in the replication.
DECLARE @publication AS sysname; DECLARE @table AS sysname; DECLARE @filterclause AS nvarchar(500); DECLARE @filtername AS nvarchar(386); DECLARE @schemaowner AS sysname; SET @publication = N'SQL01_demo_tb01'; SET @table = N'tblMillionsRows'; SET @schemaowner = N'dbo'; EXEC sp_addarticle @publication = @publication, @article = @table, @source_object = @table, @source_owner = @schemaowner, @schema_option = 0x80030F3, @vertical_partition = N'true', @type = N'logbased', @filter_clause = @filterclause; EXEC sp_articlecolumn @publication = @publication, @article = @table; EXEC sp_startpublication_snapshot @publication = 'SQL01_demo_tb01', @publisher = 'SQL01'
With all set, let’s do some tests. First updating the heap table and seeing if something is replicated.
UPDATE tblMillionsRows SET smallColumn = N'DEMO' WHERE id < 10000 GO
After the update, I ran the script below to see the transactions and commands available to replicate and nothing changed.
SELECT * FROM distribution.dbo.MSrepl_Commands SELECT * FROM distribution.dbo.MSrepl_Transactions EXEC sp_browsereplcmds
But, when I change one row running the update below I could see a new command to replicate in the another server.
UPDATE tblMillionsRows SET smallColumn = N'DEMO1' WHERE id < 10000 GO
In conclusion, SQL Server won’t replicate updates that don’t change the value. You can see more about updates in my post.
Be careful when doing updates, because if the table is replicated and you change millions rows the transaction replication will create one command for each updated row.