2012-03-16 2 views
0

내 작업은 데이터베이스에서 두 테이블의 데이터를 비교하여 유사도를 얻는 것입니다 (예 : ). 각 테이블에 5 개의 레코드가 있으면 테이블 A의 각 레코드를 모두 비교해야합니다. 유사성을 얻기 위해 테이블 ​​B에있는 레코드. 하나의 스레드를 사용하기 전에 각 테이블에 500 개의 레코드가 있고 4 분이 사용됩니다. 지금 당장 4 개의 스레드를 사용하며 30 분 사용합니다! 여기에 제 아이디어가 있습니다. 첫 번째 테이블을 4 개의 테이블로 나눕니다. 각각의 데이터를 저장하고 스레드 풀에서 4 개의 스레드를 사용하여 비교를 시작합니다. 코드는 p1, p2입니다.멀티 스레딩을 사용하여 프로그램이 훨씬 느려짐

Deduplication d = new Deduplication(pr2, threshold); 

Func<List<ParentRecord>, List<ParentRecord>> method = d.Find; 

for (int i = 0; i < 4; i++) 
{ 
    IEnumerable<ParentRecord> temp = pr1.Skip(i*part).Take(part); 
    method.BeginInvoke(temp.ToList(), CallBackMethod, method); 
} 

private void CallBackMethod(IAsyncResult result) 
{ 
    countThread++; 

    var target = (Func<List<ParentRecord>, List<ParentRecord>>)result.AsyncState; 
    List<ParentRecord> p=target.EndInvoke(result); 
    lock (_locker) 
    { 
     records.AddRange(p); 
    } 
    if (countThread > 3) 
    { 
     this.BeginInvoke(new PopulateDelegate(PopulateGridView), new object[] { records }); 
    } 
} 

private void PopulateGridView(List<ParentRecord> p) 
{ 
    dataGridViewParent.DataSource = p; 
    dataGridViewDuplication.DataSource = null; 
} 

죄송합니다. 멀티 스레딩을 처음 접해 보았습니다. 아이디어가 약간 어리석은 것 같아서 감사 드리며, 감사드립니다. 감사합니다.

업데이트

public List<ParentRecord> Find() 
    { 
     List<ParentRecord> result = new List<ParentRecord>(); 

     foreach (ParentRecord p1 in DataSource1) 
     { 
    List<DuplicateRecord> addedDuplicateRecords = new List<DuplicateRecord>(); 
      int num = 0; 
      foreach (ParentRecord p2 in DataSource2) 
      { 

       //Check if these two rows have the same primary keys 
       if (p1.PrimaryKey != p2.PrimaryKey) 
       { 
        float similarity = 0F; 
        //Check if these two rows are the simply the same 
       if (p1.CompareRow.ToUpper() == p2.CompareRow.ToUpper()) similarity = 1; 
        else similarity = GetSimilarity(p1.CompareRow, p2.CompareRow); 
        if (similarity >= threshold) 
        { 
         DuplicateRecord duplicateRecord = new DuplicateRecord(); 
         duplicateRecord.PrimaryKey = p2.PrimaryKey; 
         duplicateRecord.CompareToRow = p2.CompareRow; 
         duplicateRecord.Similarity = similarity; 
         addedDuplicateRecords.Add(duplicateRecord); 
         num++; 
        } 
       } 
      } 
      //Check if there are any reocrds meet the threadhold 
      if (num > 0) 
      { 
       ParentRecord parentRecord = new ParentRecord(); 
       parentRecord.PrimaryKey = p1.PrimaryKey; 
       parentRecord.CompareRow = p1.CompareRow; 
       parentRecord.duplicateRecordList = addedDuplicateRecords; 
       result.Add(parentRecord); 
      } 
     } 
     return result; 
    } 

    private float GetSimilarity(object obj1, object obj2) 
    { 
     float similarity = 1; 


     MatchsMaker match = new MatchsMaker(obj1.ToString(), obj2.ToString()); 

     similarity = match.Score; 


     return similarity; 
    } 

} 
+0

d.Find에 대한 코드를 게시 할 수 있습니까? 이것이 문제가되어야 할 곳입니다. – Yaur

+0

pls 업데이트 –

답변

0

이 무엇을 이해하기 하드. 여러 스레드의 쿼리를 단계별로 실행하지 않고 잘 만들어진 쿼리를 사용하거나 메모리에 모든 데이터를 읽음으로써 문제를 완전히 해결하려고합니다.

0

나는 비즈니스 계층에서 교착 상태에 있거나 데이터베이스에서 테이블 수준 잠금을 획득하고있는 것으로 생각됩니다. 내 머리 위로 떨어져

, 대안 :

  • DataReaders 나란히
  • 가 데이터베이스 커서가 (이 될 수있는 합법적 인 사용)
  • 레코드 수를 비교 기준으로
  • 을 읽는 INNER JOIN
  • CTE를하는 일련의 경우

(SQL Server를 사용하는 가정) 당신은 단지 500 개의 레코드로 성능 테스트를 수행하고 있습니다. 이러한 접근 방법 중 몇 분이 걸릴 것 같지 않습니다.

+0

을 참조하십시오. 그러나 모든 데이터가 더 이상 데이터베이스에 저장되지 않아 다른 배열 목록으로 복사됩니다. 그래도 추측 할 수 있습니까? –

관련 문제