2012-10-22 2 views
10

SQL CE를 실행하는 800 개의 모바일 클라이언트에 병합 복제가 설정된 SQL 서버가 있습니다.병합 복제 데이터베이스의 삽입물이 매우 느립니다.

서버의 리소스가 충분하고 회사 내부와 외부의 회선 수가 충분하지 않은 경우 일반적으로 클라이언트와 서버 간의 복제가 좋지만 간헐적 인 오류가 발생하여 추적 할 수 없습니다.

어제 우리 메인 테이블 중 하나에 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. 삽입 및 동기화에서 사용되는 격리 수준은 무엇입니까? 일반적으로 insert는 문제가되지 않습니다. 2. 몇 개의 색인이 있습니까? 3. 증분이 아닌 인덱스가 있으며 레코드가 끝 대신 트리 구조의 중간에 삽입 됩니 까? 4. 클러스터 된 인덱스가 있습니까? – Farfarak

+0

1. 격리 수준에서는 확실하지 않습니다. 표준 삽입 문입니다. 2. 1 개의 표준 인덱스가있는 테이블 A에 삽입됩니다. 그러나 병합 복제 트리거는 다른 많은 테이블에 막대합니다. 3. 테이블에 없습니다. 아니요 –

+0

1. 복제 중에 호출되는 쿼리를 사용하면 복제 프로세스가 케이스 힙의 전체 테이블을 차단할 수 있습니다 (클러스터 된 인덱스가없는 경우). 2. 테이블? – Farfarak

답변

0

지금까지는 인덱스 만 도움이되었지만이 시스템에서는 병합 복제가 제대로 설정되지 않은 것으로 보입니다.

그러나 트리거를 실행하지 않고 대량 삽입을 사용한 다음 sp_addtabletocontents를 사용하여 문제가 해결되었습니다.이 병합 복제가 다른되지 변경했다 다른 연결된 테이블을 통지 있도록 보조 노트로

우리는 우리가 대량 삽입을 한 후

업데이트 테이블 열 1 = 열 1

을 설정 기본 업데이 트를해야했다 모든 데이터가 올바르게 전파되었습니다.

8

우리는 최근 우리 시스템에서 똑같은 동작을 경험했습니다. 이는 사용자의 것과 매우 유사합니다. 그 이유는 msmerge_contents와 msmsmerge_current_partition_mappings에 엄청난 양의 데이터가 있었기 때문에 SQL Profiler에서 읽은 행 수를 보면 누락 된 인덱스 일 수 있습니다. 나는이 당신을 도울 수 있기를 바랍니다

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]) 

, 그것은 우리를 도와 낮은 :

이 두 개의 인덱스를 추가 30 분 전 해결

이 (49 000 000 테이블에 대한 하나의 간단한 삽입에 대한 읽기는 조금 많이 보였다) 쿼리 시간은 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