2012-10-22 69 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