일부 시나리오에서는 SqlPackage 작업이 예상보다 오래 걸리거나 완료하지 못합니다. 이 문서에서는 이러한 작업의 성능 문제를 해결하거나 개선하기 위해 자주 제안되는 몇 가지 전술에 대해 설명합니다. 사용 가능한 매개 변수 및 속성을 이해하기 위해 각 작업에 대한 특정 설명서 페이지를 읽는 것이 권장되며 이 문서는 SqlPackage 작업을 조사하는 시작점으로 사용됩니다.
전체 전략
일반적으로 DacFramework.msi를 통해 설치된 .NET Framework 버전 대신 .NET 버전의 SqlPackage를 통해 더 나은 성능을 얻을 수 있습니다.
만약 SqlPackage dotnet 도구를 설치할 수 없다면, 이 도구는 명령 프롬프트에서 어떤 디렉터리에서든 SqlPackage 명령을 실행할 수 있게 해줍니다:
- 운영 체제(Windows, macOS 또는 Linux)용 .NET 8에서 SqlPackage에 대한 zip을 다운로드합니다.
- 다운로드 페이지에서 지시한 대로 아카이브를 압축 해제하세요.
- 명령 프롬프트를 열고 디렉터리(
cd)를 SqlPackage 폴더로 변경합니다.
최신 버전의 SqlPackage를 사용하세요. 성능 향상과 버그 수정이 정기적으로 공개됩니다.
가져오기/내보내기 서비스를 SqlPackage로 대체하기
가져오기/내보내기 서비스를 사용하여 데이터베이스를 가져오거나 내보내려고 시도한 경우 SqlPackage를 사용하여 선택적 매개 변수 및 속성에 대한 더 많은 제어를 통해 동일한 작업을 수행할 수 있습니다.
BACPAC 가져오기 최적화 블로그 게시물 - SqlPackage 올바르게 사용하기! 가져오기에 Import/Export 서비스 .bacpac 대신 SqlPackage를 사용하는 단계를 안내합니다.
가져오기의 경우 예제 명령은 다음과 같습니다.
./SqlPackage /Action:Import /sf:<source-bacpac-file-path> /tsn:<full-target-server-name> /tdn:<a new or empty database> /tu:<target-server-username> /tp:<target-server-password> /df:<log-file>
내보내기의 경우 예제 명령은 다음과 같습니다.
./SqlPackage /Action:Export /tf:<target-bacpac-file-path> /ssn:<full-source-server-name> /sdn:<source-database-name> /su:<source-server-username> /sp:<source-server-password> /df:<log-file>
사용자 이름과 비밀번호 대신 다중 인증을 사용하여 Microsoft Entra 인증으로 인증하세요. 사용자 이름 및 암호 매개 변수를 /ua:true 및 /tid:"contoso.onmicrosoft.com"으로 대체할 수 있습니다.
Diagnostics
SqlPackage에서 오류 및 예기치 않은 동작 진단은 진단 로그 및 진단 패키지에서 지원됩니다. 진단 로그는 문제 해결에 필수적이며 /DiagnosticsFile:<filename> 매개 변수를 사용하여 파일에 캡처됩니다.
파라미터를 통해 /DiagnosticsLevel 진단 출력의 세부 수준을 제어할 수 있습니다. 더 자세한 내용을 확인하려면 Verbose 및 Information 값을 사용하세요.
SqlPackage를 실행하기 전에 환경 변수를 DACFX_PERF_TRACE=true 설정하여 성능 관련 트레이스 데이터를 기록하세요. 트레이스 데이터는 로그 출력을 증가시키므로, 성능 문제를 진단할 때만 포함하세요. PowerShell에서 이 환경 변수를 설정하려면 다음 명령을 사용합니다.
Set-Item -Path Env:DACFX_PERF_TRACE -Value true
SqlPackage 162.5 이후에서는 문제 해결을 돕기 위한 진단 패키지를 생성할 수 있습니다. 진단 패키지에는 SqlPackage 버전, 실행된 명령, 원본 및 대상 데이터베이스 모델에 대한 정보 및 명령의 출력이 포함됩니다. 진단 패키지를 생성하려면 /DiagnosticsPackageFile:<filename> 매개 변수를 사용합니다.
일반적인 문제
시간 제한 오류
타임아웃 문제에 대해서는 다음 속성을 사용하여 SqlPackage와 SQL 인스턴스 간의 연결을 조정하세요:
-
/p:CommandTimeout=: 쿼리가 실행될 때 명령어 타임아웃을 초 단위로 지정합니다. 기본값: 60 -
/p:DatabaseLockTimeout=: 데이터베이스 잠금 시간 제한(초)을 지정합니다. 무한정 기다리려면-1을 사용합니다. 기본값: 60 -
/p:LongRunningCommandTimeout=: 장기 실행 명령 시간 제한(초)을 지정합니다. 기본 값0는 무한히 기다립니다.
클라이언트 리소스 사용량
내보내기 및 추출 명령의 경우, SqlPackage는 테이블 데이터를 BACPAC 또는 DACPAC 파일에 쓰기 전에 임시 디렉터리에 전달하여 버퍼링합니다. 이 저장 용량은 클 수 있으며, 내보내기 위한 데이터의 전체 크기에 상대적으로 적용됩니다.
/p:TempDirectoryForTableData=<path> 속성을 사용하여 대체 임시 디렉터리를 지정합니다.
SqlPackage는 메모리에서 스키마 모델을 컴파일합니다. 대규모 데이터베이스 스키마의 경우, 클라이언트 머신에서 SqlPackage를 실행하는 메모리 요구량이 상당할 수 있습니다.
낮은 서버 리소스 사용량
기본적으로 SqlPackage는 최대 서버 병렬 처리를 8로 설정합니다. 서버 자원 소모가 적으면 매개변수 값을 MaxParallelism 높이면 성능을 향상시킬 수 있습니다.
액세스 토큰
or /at: 매개변수를 /AccessToken: 사용하면 SqlPackage의 토큰 기반 인증이 가능하지만, 토큰을 명령어에 전달하는 것은 까다로울 수 있습니다. PowerShell에서 액세스 토큰 객체를 파싱할 때는 문자열 값을 명시적으로 전달하거나 토큰 속성 $()에 대한 참조를 랩핑하세요. 다음은 그 예입니다.
$Account = Connect-AzAccount -ServicePrincipal -Tenant $Tenant -Credential $Credential
$AccessToken_Object = (Get-AzAccessToken -Account $Account -Resource "https://database.windows.net/")
$AccessToken = $AccessToken_Object.Token
SqlPackage /at:$AccessToken
# OR
SqlPackage /at:$($AccessToken_Object.Token)
Connection
SqlPackage가 연결에 실패하는 경우 서버에서 암호화를 사용하도록 설정하지 않았거나 구성된 인증서가 신뢰할 수 있는 인증 기관(예: 자체 서명된 인증서)에서 발급되지 않을 수 있습니다. 암호화 없이 연결하거나 서버 인증서를 신뢰하도록 SqlPackage 명령을 변경할 수 있습니다. 가장 좋은 방법은 서버에 대한 신뢰할 수 있는 암호화된 연결을 설정할 수 있도록 하는 것입니다.
- 암호화 없이 연결:
/SourceEncryptConnection:False또는/TargetEncryptConnection:False - 서버 인증서 신뢰:
/SourceTrustServerCertificate:True또는/TargetTrustServerCertificate:True
SQL 인스턴스에 연결할 때 명령줄 매개변수가 서버에 연결되기 위해 변경이 필요할 수 있음을 나타내는 다음과 같은 경고 메시지 중 하나 이상이 나타날 수 있습니다:
The settings for connection encryption or server certificate trust may lead to connection failure if the server is not properly configured.
The connection string provided contains encryption settings which may lead to connection failure if the server is not properly configured.
SqlPackage의 연결 보안 변경에 대한 자세한 내용은 SqlPackage 161 연결 보안 개선에서 확인할 수 있습니다.
제약 조건에 대한 가져오기 작업 오류 2714
가져오기 작업을 수행할 때, 이미 객체가 존재할 경우 오류 2714를 받을 수 있습니다:
*** Error importing database:Could not import package.
Error SQL72014: Core Microsoft SqlClient Data Provider: Msg 2714, Level 16, State 5, Line 1 There is already an object named 'DF_Department_ModifiedDate_0FF0B724' in the database.
Error SQL72045: Script execution error. The executed script:
ALTER TABLE [HumanResources].[Department]
ADD CONSTRAINT [DF_Department_ModifiedDate_] DEFAULT ('') FOR [ModifiedDate];
이 오류를 해결하는 원인과 해결 방법은 다음과 같습니다.
- 가져오는 대상이 빈 데이터베이스인지 확인합니다.
- 만약 데이터베이스에 속성(SQL Server가 제약 조건에 임의 이름을 할당하는 경우)과 명시적으로 명시된 제약 조건이 있다
DEFAULT면, 같은 이름의 제약 조건이 두 번 생성될 수 있습니다. 명시적으로 지정된 모든 제약 조건을 사용하거나(DEFAULT를 사용하지 않음), 시스템에서 정의한 이름을 모두 사용하세요(DEFAULT사용). -
model.xml파일을 수동으로 편집하고 오류를 발생시키는 이름을 가진 제약 조건의 이름을 고유한 이름으로 바꾸십시오. 이 옵션은 Microsoft 지원에서 지시하고 ..bacpac손상의 위험을 초래하는 경우에만 수행해야 합니다.
스택 오버플로 예외
중첩된 문이 많은 대규모 T-SQL 스크립트는 간헐적이거나 지속적인 스택 오버플로우 예외를 일으킬 수 있습니다. 이 조건이 발생하면 오류 메시지는 텍스트 Stack overflow 와 스택 트레이스를 포함합니다:
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.Visit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor.ExplicitVisit(Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.Accept(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
Microsoft.SqlServer.TransactSql.ScriptDom.BinaryQueryExpression.AcceptChildren(Microsoft.SqlServer.TransactSql.ScriptDom.TSqlFragmentVisitor)
SqlPackage에 대한 매개 변수는 SqlPackage 프로세스를 실행하는 스레드의 최대 스택 크기를 지정하는 모든 /ThreadMaxStackSize: 명령에서 사용할 수 있습니다. 기본값은 SqlPackage를 실행하는 .NET 버전에 의해 결정됩니다. 큰 값을 설정하면 SqlPackage의 전반적인 성능에 영향을 줄 수 있습니다. 하지만 이 값을 올리면 중첩된 문장으로 인한 스택 오버플로우 예외를 해결할 수 있습니다. 가능한 한 스택 오버플로우 예외를 피하도록 T-SQL 코드를 리팩터링하세요. 리팩터링이 불가능하다면, 이 매개변수를 /ThreadMaxStackSize: 우회 방법으로 사용하세요.
매개변수를 /ThreadMaxStackSize: 사용할 때, 성능 저하가 감지되면 스택 오버플로우 예외를 해결할 수 있는 최저 값으로 반복 작업을 조정하세요. 매개변수 값은 메가바이트(MB) 단위입니다. 예를 들어, 와 100같은 10 값을 테스트할 수 있습니다.
가져오기 작업 팁
큰 테이블이 포함되어 있거나 인덱스가 많은 가져오기의 경우 /p:DisableIndexesForDataPhase=False 또는 /p:RebuildIndexesOfflineForDataPhase=True를 사용하면 성능을 향상시킬 수 있습니다. 이러한 속성은 인덱스 다시 빌드 작업이 오프라인으로 발생하거나 발생하지 않도록 각각 수정합니다. 이 속성들과 다른 속성들을 사용해 SqlPackage Import 작업을 조정할 수 있습니다.
가져오기 후에는 인덱스가 비활성화됩니다
데이터를 효율적으로 로드하기 위해, 가져오기는 데이터 단계 전에 클러스터가 아닌 인덱스를 비활성화하고 이후 재구축하는 기본 동작입니다 /p:DisableIndexesForDataPhase=True . 데이터 로드 후 재구성이 완료되기 전에 가져오기가 중단되거나 실패하면, 하나 이상의 비클러스터 인덱스는 비활성화된 상태로 유지될 수 있습니다. 비활성화된 인덱스는 메타데이터에 남아 있지만, 쿼리 옵티마이저는 이를 무시하므로 겉보기에는 성공한 것처럼 보이는 가져오기 후에도 쿼리가 느려질 수 있습니다.
비활성화된 인덱스를 찾으려면 sys.indexes 카탈로그 뷰의 열을 확인하세요is_disabled:
SELECT OBJECT_SCHEMA_NAME(object_id) AS schema_name,
OBJECT_NAME(object_id) AS table_name,
name AS index_name
FROM sys.indexes
WHERE is_disabled = 1;
비활성화된 인덱스를 다시 활성화하려면 ALTER INDEX로 다시 빌드하십시오. 테이블에서 비활성화된 모든 인덱스를 활성화하는 방법 ALTER INDEX ALL ... REBUILD :
ALTER INDEX ALL ON <schema>.<table> REBUILD;
자세한 내용은 인덱스 및 제약 조건 활성화를 참조하세요.
내보내기 작업 팁
내보내기가 트랜잭션 일관성을 가지려면, 내보내기 중에 쓰기 활동이 없거나, 트랜잭션 형태가 일치하는 데이터베이스 복사 본에서 내보내는지 확인하세요. 가져오기 중에 외래 키 제약 조건에 관한 오류가 발생하면, 내보내기 과정에서 레코드가 삽입되거나 업데이트되어 트랜잭션 일관성이 없을 수 있습니다.
내보내기 중 성능
내보내기 중 성능 저하의 흔한 원인은 해결되지 않은 객체 참조입니다. 이 문제로 인해 SqlPackage는 객체를 여러 번 해석하려고 시도하게 됩니다. 예를 들어, 테이블을 참조하는 뷰가 정의되었지만 그 테이블이 데이터베이스에 더 이상 존재하지 않는 경우입니다. 해결되지 않은 참조가 내보내기 로그에 표시되는 경우 데이터베이스의 스키마를 수정하여 내보내기 성능을 향상시키는 것이 좋습니다.
내보내기 프로세스 중에 테이블 데이터는 bacpac 파일에서 압축됩니다.
SuperFast를 NotCompressed, /p:CompressionOption 또는 Fast로 설정하면 출력 bacpac 파일의 압축 수준은 낮아지지만 내보내기 프로세스 속도는 향상될 수 있습니다.
스키마 유효성 검사를 건너뛰면서 데이터베이스 스키마 및 데이터를 가져오려면 속성을 사용하여 /p:VerifyExtraction=False를 수행합니다. 가져올 수 없는 무효의 내보내기가 생성될 수 있습니다.
내보내는 동안 디스크 공간
OS 디스크 공간이 제한되어 내보내기 중에 소진되는 경우, 데이터를 버퍼링하여 대체 디스크로 내보내는 것을 사용 /p:TempDirectoryForTableData 하세요. 이 작업에 필요한 공간은 클 수 있으며 전체 데이터베이스 크기를 기준으로 합니다. 이 속성과 다른 속성들을 설정하여 SqlPackage Export 작업을 조정할 수 있습니다.
Azure SQL 데이터베이스
다음 팁은 Azure VM(가상 머신)에서 Azure SQL Database에 대해 가져오기 또는 내보내기를 실행하는 데만 적용됩니다.
- 최상의 성능을 위해 중요 비즈니스용 또는 프리미엄 계층 데이터베이스를 사용합니다.
- VM에서 SSD 스토리지를 사용합니다.
- bacpac의 압축을 풀 수 있는 충분한 공간이 있는지 확인합니다.
- 데이터베이스와 동일한 지역의 VM에서 SqlPackage를 실행합니다.
- 가속화된 네트워킹을 VM에 사용하도록 설정합니다.
PowerShell 스크립트를 사용해 가져오기 작업에 대한 세부 정보를 수집하는 방법에 대한 자세한 내용은 Lesson Learned #211: SQLPackage 가져오기 프로세스 모니터링을 참조하세요.
추가 리소스
Azure Database 지원 블로그에는 SqlPackage의 여러 문서를 포함하여 Azure SQL 데이터베이스의 문제 해결 및 성능 튜닝에 대한 많은 문서가 포함되어 있습니다.
가장 관련성이 큰 문서 중 일부는 다음과 같습니다.
- BACPAC 가져오기 최적화 - SqlPackage 제대로 완료!
- 학습된 교훈 #535: 호환되지 않는 사용자로 인해 Azure SQL Database에서 BACPAC 가져오기 실패
- 학습된 교훈 #523: PowerShell로 SqlPackage 로그를 구문 분석하여 가져오기 시간 측정
- Azure SQL DB 내보내기/복원을 수행하는 동안 외부 데이터 원본 참조를 건너뛰는 방법
- SqlPackage/ADF를 활용하여 Azure SQL DB를 SQL MI로 마이그레이션
- 진행 중 얻은 개선 사항 #446: PowerShell을 사용하여 SQLPackage 로그 디버깅 간소화
- 관리 ID로 Sqlpackage를 사용하는 방법
- 진행 중 얻은 개선 사항 #298: sqlpackage를 사용하여 데이터베이스 내보내기의 매우 긴 소요 시간
- 진행 중 얻은 개선 사항 #281: 시스템 메모리 부족 예외로 인해 내보내기 실패
- 교훈 #281: 비즈니스 논리로 인한 bacpac 가져오기 중 CHECK 제약 조건 문제 해결
- 진행 중 얻은 개선 사항 #272: Bacpac 파일을 가져오는 중에 발생한 실행 시간 제한 만료 오류 메시지
- 진행 중 얻은 개선 사항 #213: 통합 보안이 설정된 경우 AccessToken 속성을 설정할 수 없음
- 진행 중 얻은 개선 사항 #211: SQLPackage 가져오기 프로세스 모니터링
- 진행 중 얻은 개선 사항 #51: Managed Instance - Sqlpackage.exe 통한 가져오기가 자동 증가를 허용하지 않음
- 진행 중 얻은 개선 사항 #32: SQL Server에서 Bacpac으로 여러 데이터베이스를 내보내는 방법
- 단계별: 액세스 토큰과 함께 SQLPackage를 사용하는 방법
- Azure SQL DB를 SQLPackage를 사용해 SQL Server on-premises 또는 Azure VM으로 이동할 때 콜레이션 충돌