Updating Bit fields over a linked server

  • Follow


We have been trying to implement a multi-server database solution that tracks 
millions of invoices. However, updating a bit data type status column across 
the link has proved problematic. The following update fails due to a timeout 
because of a full table scan of the remote table

SET XACT_ABORT ON
BEGIN TRAN
     UPDATE LinkedServer.Account.dbo.Invoice
     SET IsPaid = 1
     WHERE InvoiceId = 1234
COMMIT TRAN

--Query Plan:
|--Remote Update(SOURCE:(LinkedServer), OBJECT:("Account"."dbo"."Invoice"), 
SET:([LinkedServer].[Account].[dbo].[Invoice].[IsPaid] = [Expr1003]))
     |--Compute Scalar(DEFINE:([Expr1003]=(1)))
            |--Table Spool
                 
|--Filter(WHERE:([LinkedServer].[Account].[dbo].[Invoice].[InvoiceId]=(1234)))
                     |--Remote Scan(SOURCE:(LinkedServer), 
OBJECT:("Account"."dbo"."Invoice"))


However, updating a character field works fine!:
SET XACT_ABORT ON
BEGIN TRAN
     UPDATE LinkedServer.Account.dbo.Invoice
     SET CustomerName = 'Fred'
     WHERE InvoiceId = 1234
COMMIT TRAN

Query Plan:
|--Remote Query(SOURCE:(LinkedServer), QUERY:(UPDATE 
"Account"."dbo"."Invoice" set "CustomerName" = 'Fred' WHERE 
"InvoiceId"=(1234)))

So other than the appearance of this being a bug, is there any way to stop 
SQL Server from doing the full scan?  And yes, I tried OPENQUERY. It is not 
an option, since it's performance is just as bad as the full scan.

Thanks.
0
Reply Utf 1/29/2010 10:21:02 PM

Dan (Dan@discussions.microsoft.com) writes:
> We have been trying to implement a multi-server database solution that
> tracks millions of invoices. However, updating a bit data type status
> column across the link has proved problematic. The following update
> fails due to a timeout because of a full table scan of the remote table 
>... 
> --Query Plan:
>|--Remote Update(SOURCE:(LinkedServer), OBJECT:("Account"."dbo"."Invoice"), 
> SET:([LinkedServer].[Account].[dbo].[Invoice].[IsPaid] = [Expr1003]))
>      |--Compute Scalar(DEFINE:([Expr1003]=(1)))
>             |--Table Spool
>                  
>|--
Filter(WHERE:([LinkedServer].[Account].[dbo].[Invoice].[InvoiceId]=(1234)))
>                      |--Remote Scan(SOURCE:(LinkedServer), 
> OBJECT:("Account"."dbo"."Invoice"))
> 
> 
> However, updating a character field works fine!:
>...
> Query Plan:
>|--Remote Query(SOURCE:(LinkedServer), QUERY:(UPDATE 
> "Account"."dbo"."Invoice" set "CustomerName" = 'Fred' WHERE 
> "InvoiceId"=(1234)))

I was able to reproduce this with a table I just made up, and I added a
repro to your Connect bug, 
https://connect.microsoft.com/SQLServer/feedback/details/528007/updating-
bit-field-on-linked-server-fails

I can see how this could happen with newer data types like datetime2,
for which there is no matching core type in OLE DB, but it should not
happen on bit, I think.

But the general problems with linked servers is that the query plans
are generated with knowledge of what is on the other end, to the
smallest common denominator is used.
 
> So other than the appearance of this being a bug, is there any way to
> stop SQL Server from doing the full scan?  And yes, I tried OPENQUERY.
> It is not an option, since it's performance is just as bad as the full
> scan. 

Did you try EXEC AT:

  EXEC('UPDATE Account.dbo.Invoice 
        SET    IsPaid = 1
        WHERE  InvoiceID = ?', 1234) AT LinkedServer

You don't have to pass 1234 as a parameter, but I wanted to show that
it is possible.


-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
SQL 2000: http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

0
Reply Erland 1/29/2010 11:15:14 PM


Dan wrote:
> 
> We have been trying to implement a multi-server database solution that tracks
> millions of invoices. However, updating a bit data type status column across
> the link has proved problematic. The following update fails due to a timeout
> because of a full table scan of the remote table
> 
> SET XACT_ABORT ON
> BEGIN TRAN
>      UPDATE LinkedServer.Account.dbo.Invoice
>      SET IsPaid = 1
>      WHERE InvoiceId = 1234
> COMMIT TRAN
> 
> --Query Plan:
> |--Remote Update(SOURCE:(LinkedServer), OBJECT:("Account"."dbo"."Invoice"),
> SET:([LinkedServer].[Account].[dbo].[Invoice].[IsPaid] = [Expr1003]))
>      |--Compute Scalar(DEFINE:([Expr1003]=(1)))
>             |--Table Spool
> 
> |--Filter(WHERE:([LinkedServer].[Account].[dbo].[Invoice].[InvoiceId]=(1234)))
>                      |--Remote Scan(SOURCE:(LinkedServer),
> OBJECT:("Account"."dbo"."Invoice"))
> 
> However, updating a character field works fine!:
> SET XACT_ABORT ON
> BEGIN TRAN
>      UPDATE LinkedServer.Account.dbo.Invoice
>      SET CustomerName = 'Fred'
>      WHERE InvoiceId = 1234
> COMMIT TRAN
> 
> Query Plan:
> |--Remote Query(SOURCE:(LinkedServer), QUERY:(UPDATE
> "Account"."dbo"."Invoice" set "CustomerName" = 'Fred' WHERE
> "InvoiceId"=(1234)))
> 
> So other than the appearance of this being a bug, is there any way to stop
> SQL Server from doing the full scan?  And yes, I tried OPENQUERY. It is not
> an option, since it's performance is just as bad as the full scan.
> 
> Thanks.

Another thing you could try is this:

  UPDATE LinkedServer.Account.dbo.Invoice
  SET IsPaid = CAST(1 AS bit)
  WHERE InvoiceId = 1234

-- 
Gert-Jan
0
Reply Gert 1/30/2010 9:46:49 AM

Gert-Jan Strik (sorrytoomuchspamalready@xs4all.nl) writes:
> Another thing you could try is this:
> 
>   UPDATE LinkedServer.Account.dbo.Invoice
>   SET IsPaid = CAST(1 AS bit)
>   WHERE InvoiceId = 1234
 
Nope. That was my initial thought, but I tested it before I posted, and
it doesn't help.


-- 
Erland Sommarskog, SQL Server MVP, esquel@sommarskog.se

Links for SQL Server Books Online:
SQL 2008: http://msdn.microsoft.com/en-us/sqlserver/cc514207.aspx
SQL 2005: http://msdn.microsoft.com/en-us/sqlserver/bb895970.aspx
SQL 2000: http://www.microsoft.com/sql/prodinfo/previousversions/books.mspx

0
Reply Erland 1/30/2010 11:00:25 AM

3 Replies
224 Views

(page loaded in 0.076 seconds)

8/1/2012 6:50:06 PM


Reply: