2012-10-22 37 views
10

我有一个SQL服务器设置合并复制到800个移动客户端运行SQL CE。插入合并复制数据库是非常慢

服务器有足够的资源和线进出公司都绰绰有余,客户端和服务器之间的复制总体上是好的,但我们得到了一个间歇性的错误,我只是无法追查。

昨天我们需要插入550个记录到我们的主表中的一个,唯一存在的触发器是标准的合并复制的。

该插入了由于它会不断得到与尝试同步移动设备僵持14小时。

有没有人对我们如何才能避免在插入锁和如何加快整个过程中的任何建议吗?

------ -----更新

一些意见继我在单个刀片上运行探查器,我看到了很多这样的事情的

insert into dbo.MSmerge_current_partition_mappings with (rowlock) (publication_number, tablenick, rowguid, partition_id) 
      select distinct 1, mc.tablenick, mc.rowguid, v.partition_id 
      from dbo.MSmerge_contents mc with (rowlock) 
      JOIN dbo.[MSmerge_JEMProjectME_PromotionResource_PARTITION_VIEW] v with (rowlock) 
      ON mc.tablenick = 286358001 
      and mc.rowguid = v.[rowguid] 
      and mc.marker = @child_marker 
      and v.partition_id in (select partition_id from dbo.MSmerge_current_partition_mappings cpm with (rowlock) JOIN 
       dbo.MSmerge_contents mc2 with (rowlock) 
       ON cpm.rowguid = mc2.rowguid 
       and mc2.marker = @marker) 
      where not exists (select * from MSmerge_current_partition_mappings with (readcommitted, rowlock, readpast) where 
       publication_number = 1 and 
       tablenick = 286358001 and 
       rowguid = v.[rowguid] and 
       partition_id = v.partition_id) 

对于很多我不打算插入的表格......这可能是一个线索吗?

+0

1.什么是插入和同步使用的隔离级别?通常插入不应该是一个问题。 2.你有多少个索引? 3.你有没有增量的索引,会导致记录被插入到树结构的中间而不是结尾? 4.你有聚集索引吗? – Farfarak

+0

1.不确定在隔离级别..它只是一个标准的插入语句 - 2.我们插入到表A有一个标准索引..但是合并复制触发器将它粘贴到许多其他表 - 3.不在桌子上我们正在插入 - 4.否 –

+0

1.您有复制过程中正在调用的查询,它可能是复制过程阻止您的案例堆中的整个表(您没有聚集索引)2.是否有唯一的密钥表? – Farfarak

回答

0

最终只索引帮助到目前为止,它看起来像合并复制不是建立很好的在这个系统上。

然而,使用大容量插入,而不激活触发器,然后用sp_addtabletocontents解决我们的问题。

作为一个侧面说明,我们不得不做一个基本的更新

更新表设置列1 =列1

我们做了批量插入后,使合并复制通知,它已经别的变化不是其他链接的表所有数据传播正确。

8

我们最近在我们的系统中遇到了与您的系统非常相似的行为。原因是msmerge_contents和msmsmerge_current_partition_mappings中有大量数据,我们通过查看在SQL Profiler中读取的行数,发现它可能是缺少索引。 (49 000 000读取于一体,为表一个简单的插入似乎有点多)

解决了31分钟前通过增加两个指标:

CREATE NONCLUSTERED INDEX [IX_MSmerge_current_partition_mappings_PERF1] ON [dbo].[MSmerge_current_partition_mappings] 
(
    [partition_id] ASC 
) 
INCLUDE ([rowguid]) 


CREATE NONCLUSTERED INDEX [IX_msmerge_contents_PERF1] ON [dbo].[MSmerge_contents] 
(
    [marker] ASC 
) 
INCLUDE ([rowguid]) 

我希望这可以帮助你,它帮助我们降低查询时间从5分钟到10秒。

- 几个小时后...

我的同事发现了另一个指标是由另外75%进一步提高性能:

CREATE NONCLUSTERED INDEX [IX_MSmerge_current_partition_mappings_PERF2] ON [dbo].[MSmerge_current_partition_mappings] 
(
    [rowguid] ASC, 
    [partition_id] ASC 
) 

识别缺失索引 可以使用下面的脚本识别缺少的指标,用一个有望在最上面的提高性能排序(有许多这样的脚本循环,这一次是从http://www.sherbaz.com/category/sqlserver/借来的)

SELECT sys.objects.name 
, (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) AS Impact 
, 'CREATE NONCLUSTERED INDEX ix_IndexName ON ' + sys.objects.name COLLATE DATABASE_DEFAULT + ' (' + IsNull(mid.equality_columns, '') + CASE WHEN mid.inequality_columns IS NULL 
       THEN '' 
    ELSE CASE WHEN mid.equality_columns IS NULL 
        THEN '' 
     ELSE ',' END + mid.inequality_columns END + ') ' + CASE WHEN mid.included_columns IS NULL 
       THEN '' 
    ELSE 'INCLUDE (' + mid.included_columns + ')' END + ';' AS CreateIndexStatement 
, mid.equality_columns 
, mid.inequality_columns 
, mid.included_columns 
    FROM sys.dm_db_missing_index_group_stats AS migs 
      INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle 
      INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle AND mid.database_id = DB_ID() 
      INNER JOIN sys.objects WITH (nolock) ON mid.OBJECT_ID = sys.objects.OBJECT_ID 
    WHERE  (migs.group_handle IN 
     ( 
     SELECT  TOP (500) group_handle 
      FROM   sys.dm_db_missing_index_group_stats WITH (nolock) 
      ORDER BY (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) DESC)) 
     AND OBJECTPROPERTY(sys.objects.OBJECT_ID, 'isusertable')=1 
    ORDER BY 2 DESC , 3 DESC