2012-10-03 6 views
0

SQL 스크립트를 여러 번 실행해야하는 메소드가 있습니다. 이 스크립트는 데이터베이스의 테이블, 뷰, 저장 프로 시저 및 함수 작성에 사용됩니다. 100 개의 파일로 잘 작동하는이 코드를 생각해 냈습니다.프로세스 성능을 향상시키는 방법은 무엇입니까?

foreach (var folder in ActivityConstant.SourceFolders) 
{ 
    var destination = context.GetValue(this.DestinationPath) + folder; 

    // TODO: Execute all sql folders instead of each sql file. 
    // this is cmd command for %f in (*.sql) do sqlcmd /S <servername> /d <dbname> /E /i "%f" 

    foreach (var file in Directory.GetFiles(destination)) 
    { 
     var begin = DateTime.Now; 
     context.TrackBuildWarning(string.Format("Start exec sql file at {0}.", 
               DateTime.Now)); 

     Process process = new Process(); 
     process.StartInfo.UseShellExecute = false; 
     process.StartInfo.RedirectStandardOutput = true; 
     process.StartInfo.RedirectStandardError = true; 
     process.StartInfo.CreateNoWindow = true; 
     process.StartInfo.FileName = "sqlcmd.exe"; 
     process.StartInfo.Arguments = string.Format("-S {0} -d {1} -i {2} -U {3} -P {4}", 
                sqlServerName, 
                databaseName, 
                file, 
                sqlUserName, 
                sqlPassword); 
     process.StartInfo.WorkingDirectory = @"C:\"; 
     process.Start(); 
     //process.WaitForExit(); 

     context.TrackBuildWarning(
      string.Format(
       "Finished exec sql file at {0} total time {1} milliseconds.", 
       DateTime.Now, 
       DateTime.Now.Subtract(begin).TotalMilliseconds)); 
    } 
} 

이제 다음 단계로 넘어 가고 있습니다. 나는 약 600 개의 파일 (테이블, 뷰, 저장 프로 시저 및 함수)을 가진 데이터베이스로 테스트 중이며 현재 코드가 이와 같이 많은 양의 쿼리를 처리 할 수없는 것처럼 보입니다.

레코드가있는 한 약 100 개의 파일을 실행하는 데 3 ~ 5 분이 걸립니다. 이 질문을 쓰고있는 시점에이 600 개의 파일에 대해 40 분이 걸렸습니다.

내 코드를 개선하는 방법을 알고 싶습니다. 목표를 달성하기 위해 차이점을 이용하는 것이 더 나은 경우 어떤 제안도 환영합니다.

+1

파일 내용을 처리 할 때 병목 현상이 코드이며 DBMS가 아닌 것이 확실합니까? –

+1

SQL Server를 보셨습니까? 한 번에 많은 쿼리를 처리 할 수 ​​있습니까? –

+0

@JustinHarvey 어떻게 확인할 수 있습니까? – Anonymous

답변

0

파일 집합당 하나의 데이터베이스 인 경우 모든 파일/쿼리를 로그인하면 안됩니다.

+0

시간이 아주 조금 걸림 –

+0

예, 이것은 데이터베이스 하나뿐입니다. 매번 로그인하지 않아도 스크립트를 실행하는 방법은 무엇입니까? – Anonymous

2

동시에 600 개의 프로세스를 시작합니다. 성능이 좋지 않거나 RAM을 많이 차지합니다. 스와핑이 발생합니까?

또한 SQL 서버에 많은로드가 발생하며 메모리 문제 일 수도 있습니다.

쿼리를 순차적으로 실행하거나 적어도 한 번에 몇 개만 실행하십시오. 사이드만큼

편집

SqlCommand를 사용하는 대신 외부 프로세스를 시작 고려해야합니다 유의하십시오.

+0

SQL 파일에 CREATE (테이블, 뷰, 저장 프로 시저) 명령이 포함되어 있습니다. 내가 생각하기에 SQL 명령은 SELECT, INSERT, UPDATE 및 DELETE에서만 작동합니다. 다른 아이디어가 있습니까? – Anonymous

+0

'SqlCommand'도 DML과 함께 작동하지만 (CREATE, ALTER 등),'GO' 문은 처리하지 않습니다. 각 GO에서 파일을 분할하고 별도의 SqlCommand에서 각 분할 된 부분을 실행하거나 [여기]를 볼 수 있습니다 (http://stackoverflow.com/a/40830/401728) –

0

성능을 향상시키는 가장 유용한 방법은 실제 SQL 명령의 실행을 응용 프로그램으로 옮기는 것입니다.

  • 많은 프로세스 생성 방지 (평행 600?!)
  • 반복 연결 (프로세스 당 하나 이상) (인해 결정적 (undeterministic) 실행 순서로)
  • 차선 잠금 경합

나는 스크립트를 리소스로 저장 한 다음 SqlConnection에서 실행하는 것을 살펴볼 것입니다.

적용 가능한 경우 거래 관리를 생각해보십시오. 이를 처리하는 가장 쉬운 방법은 각각 각 '스크립트'에 대한 새 연결입니다. 매번 동일한 연결 문자열을 사용하면이 연결은 풀 프레임으로 으로 자동 풀링됩니다.

0

당신은 그 (것)을 실행하기 전에 파일을 병합하려고 할 수 있습니다

 using (var merged = File.OpenWrite("merged.sql")) 
     { 
      foreach (var file in Directory.GetFiles(destination)) 
      { 
       var data = File.ReadAllBytes(file); 
       merged.Write(data, 0, data.Length); 
      } 
     } 
     //continue with "merged.sql" as source file for the sqlcmd 

또한,이 작업을 위해 기존 도구의 다양성이, "데이터베이스 배포 도구"또는 일부 등을 위해 구글.

관련 문제