針對 SqlPackage 的問題與效能進行疑難排解
在部分案例中,SqlPackage 作業花費的時間超乎預期或無法完成。 此文章描述一些常見的建議策略,以針對這些作業進行疑難排解或改善效能。 儘管建議您閱讀每個動作適用的特定文件頁面來了解可用的參數與屬性,但可將此文章當作調查 SqlPackage 作業的起點。
整體策略
一般指導方針是透過 .NET 版本的 SqlPackage 取得更好的效能,而不是透過 DacFramework.msi 安裝的 .NET Framework 版本。
如果您無法安裝 SqlPackage dotnet 工具,可從任何目錄的命令提示字元執行 SqlPackage 命令:
- 在適用於您作業系統 (Windows、macOS 或 Linux) 的 .NET 8 上,下載 SqlPackage 的 zip 檔案。
- 依照下載頁面上的指示將封存解壓縮。
- 開啟命令提示字元,並將目錄切換 (
cd
) 到 SqlPackage 資料夾。
請務必使用最新可用的 SqlPackage 版本,因為效能提升與錯誤 (Bug) 修正程式會定期發行。
以 SqlPackage 取代匯入/匯出服務
如果曾嘗試使用匯入/匯出服務來匯入或匯出資料庫,您可以使用 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 驗證 (先前稱為 Azure Active Directory) 進行驗證。 以使用者名稱與密碼參數取代 /ua:true
與 /tid:"yourdomain.onmicrosoft.com"
。
常見問題
逾時錯誤
針對逾時相關問題,您可以使用下列屬性來調整 SqlPackage 與 SQL 執行個體之間的連線:
/p:CommandTimeout=
:指定執行查詢時的命令逾時 (以秒為單位)。 預設值:60/p:DatabaseLockTimeout=
:指定資料庫鎖定逾時 (以秒為單位)。 -1 可用來無限期等候,預設值:60/p:LongRunningCommandTimeout=
:指定長時間執行的命令逾時 (以秒為單位)。 預設值 0 是用來無限期等候。
用戶端資源耗用量
針對匯出與擷取命令,先將資料表資料傳遞到暫存目錄以進行緩衝處理,然後再寫入到 bacpac/dacpac 檔案。 此儲存體需求可能很大 (相對於要匯出資料的完整大小)。 使用 /p:TempDirectoryForTableData=<path>
屬性來指定替代的暫存目錄。
結構描述模型會在記憶體中編譯,因此,針對大型資料庫結構描述,執行 SqlPackage 的用戶端電腦上的記憶體需求可能相當重要。
伺服器資源耗用量降低
根據預設,SqlPackage 會將伺服器平行處理原則上限設定為 8。 如果您注意到伺服器資源耗用量降低,則增加 MaxParallelism
參數的值可以提升效能。
存取權杖
使用 /AccessToken:
或 /at:
參數可針對 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)
連線
如果 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];
以下是解決此錯誤的原因和解決方案:
- 確認您要匯入的目的地是否為空資料庫。
- 如果資料庫具有使用 DEFAULT 屬性的條件約束 (其中 SQL Server 為條件約束指派隨機名稱) 和明確命名的條件約束,則可能會建立兩次具有相同名稱的條件約束。 您應使用所有明確命名的條件約束 (不使用 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 的參數 /ThreadMaxStackSize:
可在所有命令上使用,這會指定執行 SqlPackage 程序之執行緒的堆疊大小上限。 預設值由執行 SqlPackage 的 .NET 版本所決定。 設定大型值可能會影響 SqlPackage 的整體效能,不過增加此值可能會解決巢狀陳述式所造成的堆疊溢位例外狀況。 建議重構 T-SQL 程式碼,以盡可能避免堆疊溢位例外狀況,但 /ThreadMaxStackSize:
參數可作為因應措施。
使用 /ThreadMaxStackSize:
參數時,如果注意到效能影響,建議將重複的作業微調為解析堆疊溢位例外狀況的最低值。 參數的值以百萬位元組 (MB) 為單位,作為因應措施進行測試的範例值包括 10 和 100。
診斷
記錄是疑難排解不可或缺的。 使用 /DiagnosticsFile:<filename>
參數,將診斷記錄擷取至檔案。
您可以先設定環境變數 DACFX_PERF_TRACE=true
來記錄更多效能相關的追蹤資料,然後再執行 SqlPackage。 若要在 PowerShell 中設定此環境變數,請使用下列命令:
Set-Item -Path Env:DACFX_PERF_TRACE -Value true
匯入動作提示
針對包含大型資料表的匯入或具有許多索引的資料表,使用 /p:RebuildIndexesOfflineForDataPhase=True
或 /p:DisableIndexesForDataPhase=False
可以提升效能。 這些屬性會分別將索引重建作業修改為離線發生或不發生。 那些屬性與其他屬性可用來微調 SqlPackage 匯入 (部分機器翻譯) 作業。
匯出動作提示
匯出期間效能降低的一個常見原因是無法解析的物件參考,這會導致 SqlPackage 嘗試多次解析該物件。 例如,定義了參考資料表的檢視,但該資料表已不存在於資料庫中。 如果匯出記錄中出現無法解析的參考,請考慮更正資料庫的結構描述來提升匯出效能。
在匯出期間 OS 磁碟空間受限與用盡的情況下,使用 /p:TempDirectoryForTableData
可在替代磁碟上緩衝處理要匯出的資料。 此動作所需的空間可能很大 (相對於資料庫的完整大小)。 該屬性與其他屬性可用來微調 SqlPackage 匯出 (部分機器翻譯) 作業。
在匯出流程期間,會在 bacpac 檔案中壓縮資料表資料。 使用設為 Fast
、SuperFast
或 NotCompressed
的 /p:CompressionOption
,可能會改善匯出流程速度,同時減少對輸出 bacpac 檔案壓縮。
若要在略過結構描述驗證時取得資料庫結構描述與資料,請使用 /p:VerifyExtraction=False
屬性來執行匯出 (部分機器翻譯)。 有可能會產生無法匯入的無效匯出。
Azure SQL Database
下列提示是針對從 Azure 虛擬機器 (VM) 執行匯入或匯出 Azure SQL Database 的特定提示:
- 使用業務關鍵或進階層資料庫來獲得最佳效能。
- 在 VM 上使用 SSD 儲存體。
- 請確定有足夠的空間來解壓縮 bacpac。
- 從與資料庫相同區域中的 VM 執行 SqlPackage。
- 在 VM 中啟用加速網路。
如需利用 PowerShell 指令碼收集關於匯入操作的更多資訊的詳細資訊,請參閱經驗傳承 #211:監視 SQLPackage 匯入程序。
更多資源
Azure 資料庫支援部落格包含許多文章,涉及 Azure SQL 資料庫的疑難排解和效能微調,包括有關 SqlPackage 的數篇文章。
其中一些最相關的文章包括:
- 使用 SqlPackage/ADF 將 Azure SQL DB 移轉至 SQL MI
- 經驗傳承 #446:使用 PowerShell 簡化 SQLPackage 記錄偵錯
- 如何搭配受控識別使用 Sqlpackage
- 經驗傳承 #298:使用 sqlpackage 匯出資料庫需要很長時間
- 經驗傳承 #281:匯出因系統記憶體不足的例外狀況而失敗
- 經驗傳承 #281:對因商務邏輯導致匯入 bacpac 的 CHECK 條件約束問題進行疑難排解
- 經驗傳承 #272:匯入 Bacpac 檔案出現「執行逾時已過期」錯誤訊息
- 經驗傳承 #213:如果已設定整合式安全性,則無法設定 AccessToken 屬性
- 經驗傳承 #211:監視 SQLPackage 匯入處理程序
- 經驗傳承 #51:受控執行個體 - 透過 Sqlpackage.exe 的匯入不允許自動成長
- 經驗傳承 #32:如何將多個資料庫從 SQL Server 匯出至 Bacpac
- 逐步解說:如何搭配存取權杖使用 SQLPackage
- 使用 SQLPackage 將 Azure SQL DB 移至內部部署的 SQL server 或 Azure VM 時出現定序衝突。