日期:2014-05-17  浏览次数:20632 次

update语句中的使用了链接服务器,为什么执行非常慢,有什么方法可以改进?
------------------------------
RemoteServer是链接服务器,创建语句如下:
------------------------------
EXEC sp_addlinkedserver 
  'RemoteServer', 
  '', 
  'MSDASQL', 
  NULL, 
  NULL, 
  'DRIVER={SQL Server};SERVER=183.22.209.193;UID=sa;PWD=abc123;'
------------------------------
--说明:本地数据库s_data,与外网远端数据库s_data结构完全相同,都有相同的表my_table, 其中id_no是表的主键值。
--本地数据库与远端SQL使用ADSL连通。
--当本地SQL数据库中my_table表的内容变化时,我根据内容对远端SQL表做相应更新。
--现在测试结果如下:
------------------------------
--以下语句的查询时间是3秒左右。正常。
select b.aaa, a.aaa, b.bbb, a.bbb
from RemoteServer.s_data.dbo.my_table b
left outer join my_table a on a.id_no = b.id_no
where b.id_no = 'FA123'
------------------------------
--以下语句的执行时间是5秒左右。也正常。
update b SET aaa = 'test-a-001', bbb = 'test-b-002'
from RemoteServer.s_data.dbo.my_table b
left outer join my_table a on a.id_no = b.id_no
where b.id_no = 'FA123'
------------------------------
--以下语句的执行时间要10分钟多。实在太慢了,不知道是什么原因?
update b SET aaa = a.aaa, bbb = a.bbb
from RemoteServer.s_data.dbo.my_table b
left outer join my_table a on a.id_no = b.id_no
where b.id_no = 'FA123'




------解决方案--------------------
SQL code

--可以考虑使用join 而不是 left join ,除非你需要把匹配不上的列更新为null
--如果数据量很大,我怀疑是数据太多导致了锁升级
WHILE 1 = 1
BEGIN
update top(5000) b SET aaa = a.aaa, bbb = a.bbb
from RemoteServer.s_data.dbo.my_table b
join my_table a on a.id_no = b.id_no
where b.id_no = 'FA123' and isnull(b.aaa,'') <> (a.bbb,'')
  IF @@rowcount < 5000 BREAK;
END
GO

------解决方案--------------------
inner join 是没有null值的,outer join是有的。
------解决方案--------------------
内连接比外连接性能要好,具体为什么会好,left join on 后面的条件仅仅是关联的条件,不能作为过滤条件,所以在利用索引方面会变差,性能也就会变差