10

SQL CE を実行している 800 台のモバイル クライアントへのマージ レプリケーションを使用してセットアップされた SQL サーバーがあります。

サーバーには十分なリソースがあり、会社の内外の回線は十分すぎるほどです。クライアントとサーバー間のレプリケーションは一般的に良好ですが、追跡できない断続的なエラーが発生しています。

昨日、メイン テーブルの 1 つに 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)

私が挿入することを意図していない多くのテーブルについて...これは手がかりになるでしょうか?

4

2 に答える 2

8

最近、私たちのシステムで同じ動作が発生しましたが、これはあなたのシステムと非常によく似ています。その理由は、msmerge_contents と msmsmerge_current_partition_mappings の大量のデータであり、SQL プロファイラーで読み取られた行数を調べて、インデックスが欠落している可能性があることに気付きました。(テーブルの 1 つの単純な挿入で 49 000 000 の読み取りは少し多いように見えました)

2 つのインデックスを追加することで 30 分前に解決しました。

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
于 2012-10-31T13:47:44.937 に答える
0

結局、インデックスはこれまでのところ役に立ちましたが、このシステムではマージ レプリケーションがうまく設定されていないようです。

ただし、トリガーを起動せずに一括挿入を使用してから sp_addtabletocontents を使用すると、問題が解決しました。

補足として、基本的な更新を行う必要がありました

テーブル セットの更新列 1 = 列 1

一括挿入を行った後、マージレプリケーションが他のリンクされたテーブルに変更されたことを通知した後、そうでなければすべてのデータが正しく伝播されませんでした。

于 2013-06-24T10:55:08.853 に答える