Memecahkan masalah dan performa dengan SqlPackage

Dalam beberapa skenario, operasi SqlPackage membutuhkan waktu lebih lama dari yang diharapkan atau gagal diselesaikan. Artikel ini menjelaskan beberapa taktik yang sering disarankan untuk memecahkan masalah atau meningkatkan performa operasi ini. Artikel ini berfungsi sebagai titik awal dalam menyelidiki operasi SqlPackage, meskipun disarankan untuk membaca halaman dokumentasi spesifik untuk setiap tindakan guna memahami parameter dan properti yang tersedia.

Strategi keseluruhan

Sebagai pedoman umum, performa yang lebih baik dapat diperoleh melalui versi .NET SqlPackage alih-alih versi .NET Framework yang diinstal melalui DacFramework.msi.

Jika Anda tidak dapat menginstal alat dotnet SqlPackage, yang memungkinkan Anda menjalankan perintah SqlPackage dari command prompt di direktori mana pun:

  1. Unduh zip untuk SqlPackage di .NET 8 untuk sistem operasi Anda (Windows, macOS, atau Linux).
  2. Unzip arsip sesuai petunjuk di halaman unduhan.
  3. Buka perintah dan ubah direktori (cd) ke folder SqlPackage.

Gunakan versi terbaru dari SqlPackage yang tersedia, karena peningkatan performa dan perbaikan bug dirilis secara berkala.

Ganti SqlPackage untuk Layanan Impor/Ekspor

Jika Anda mencoba menggunakan Layanan Impor/Ekspor untuk mengimpor atau mengekspor database, Anda dapat menggunakan SqlPackage untuk melakukan operasi yang sama dengan kontrol lebih besar pada parameter dan properti opsional. Postingan blog Mengoptimalkan Impor BACPAC - SqlPackage dengan Benar! menelusuri langkah-langkah untuk menggunakan SqlPackage alih-alih Layanan Impor/Ekspor dalam .bacpac impor.

Untuk Impor, contoh perintah adalah:

./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>

Untuk Ekspor, contoh perintah adalah:

./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>

Gunakan autentikasi multifaktor sebagai alternatif nama pengguna dan kata sandi, untuk autentikasi dengan autentikasi Microsoft Entra. Ganti parameter nama pengguna dan kata sandi untuk /ua:true dan /tid:"contoso.onmicrosoft.com".

Diagnostics

Mendiagnosis kesalahan dan perilaku tak terduga di SqlPackage didukung oleh log diagnostik dan paket diagnostik. Log diagnostik sangat penting untuk pemecahan masalah dan diambil ke file dengan parameter /DiagnosticsFile:<filename>.

Kendalikan tingkat detail dalam output diagnostik melalui /DiagnosticsLevel parameter. Gunakan nilai Information dan Verbose untuk mendapatkan detail lebih lanjut.

Catat data jejak terkait kinerja dengan mengatur DACFX_PERF_TRACE=true variabel lingkungan sebelum menjalankan SqlPackage. Data jejak meningkatkan output log, jadi hanya menyertakan data tersebut saat mendiagnosis tantangan kinerja. Untuk mengatur variabel lingkungan ini di PowerShell, gunakan perintah berikut:

Set-Item -Path Env:DACFX_PERF_TRACE -Value true

Di SqlPackage 162.5 dan versi lebih baru, Anda dapat membuat paket diagnostik untuk membantu pemecahan masalah. Paket diagnostik berisi versi SqlPackage, perintah yang dijalankan, informasi tentang model database sumber dan target, dan output perintah. Untuk menghasilkan paket diagnostik, gunakan parameter /DiagnosticsPackageFile:<filename>.

Masalah umum

Kesalahan batas waktu

Untuk masalah timeout, gunakan properti berikut untuk menyetel koneksi antara SqlPackage dan instance SQL:

  • /p:CommandTimeout=: Menentukan batas waktu perintah dalam detik ketika kueri dijalankan. Bawaan: 60
  • /p:DatabaseLockTimeout=: Menentukan batas waktu penguncian database dalam detik. Gunakan -1 untuk menunggu tanpa batas waktu. Bawaan: 60
  • /p:LongRunningCommandTimeout=: Menentukan batas waktu perintah yang berjalan lama dalam detik. Nilai default, 0, menunggu tanpa batas waktu.

Konsumsi sumber daya klien

Untuk perintah ekspor dan ekstrak, SqlPackage mengirimkan data tabel ke direktori sementara untuk buffer sebelum menulisnya ke file BACPAC atau DACPAC. Kebutuhan penyimpanan ini bisa besar dan relatif terhadap ukuran penuh data yang akan diekspor. Tentukan direktori sementara alternatif dengan properti /p:TempDirectoryForTableData=<path>.

SqlPackage mengompilasi model skema di memori. Untuk skema basis data besar, kebutuhan memori pada mesin klien yang menjalankan SqlPackage bisa sangat signifikan.

Konsumsi sumber daya server rendah

Secara default, SqlPackage mengatur paralelisme server maksimum ke 8. Jika Anda melihat konsumsi sumber daya server rendah, meningkatkan nilai MaxParallelism parameter dapat meningkatkan kinerja.

Token akses

Menggunakan /AccessToken: parameter or /at: memungkinkan autentikasi berbasis token untuk SqlPackage, tetapi meneruskan token ke perintah bisa menjadi rumit. Jika Anda mem-parse objek token akses di PowerShell, secara eksplisit berikan nilai string atau bungkus referensi ke properti token di $(). Contohnya:

$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

Jika SqlPackage gagal tersambung, server mungkin tidak mengaktifkan enkripsi atau sertifikat yang dikonfigurasi mungkin tidak dikeluarkan dari otoritas sertifikat tepercaya (seperti sertifikat yang ditandatangani sendiri). Anda dapat mengubah perintah SqlPackage agar tersambung tanpa enkripsi atau mempercayai sertifikat server. Praktik terbaik adalah memastikan bahwa koneksi terenkripsi tepercaya ke server dapat dibuat.

  • Sambungkan tanpa enkripsi: /SourceEncryptConnection:False atau /TargetEncryptConnection:False
  • Sertifikat server kepercayaan: /SourceTrustServerCertificate:True atau /TargetTrustServerCertificate:True

Anda mungkin melihat satu atau lebih pesan peringatan berikut saat terhubung ke instance SQL, yang menunjukkan bahwa parameter baris perintah mungkin memerlukan perubahan untuk terhubung ke server:

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.

Informasi selengkapnya tentang perubahan keamanan koneksi di SqlPackage tersedia dalam Peningkatan Keamanan Koneksi di SqlPackage 161.

Kesalahan tindakan impor 2714 untuk batasan

Saat Anda melakukan aksi impor, Anda mungkin menerima error 2714 jika objek sudah ada:

*** 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];

Berikut adalah penyebab dan solusi untuk mengatasi kesalahan ini:

  1. Pastikan bahwa tujuan database yang Anda impor adalah kosong.
  2. Jika database Anda memiliki batasan yang menggunakan DEFAULT atribut (di mana SQL Server memberikan nama acak pada batasan tersebut) dan batasan yang secara eksplisit bernama, batasan dengan nama yang sama mungkin dibuat dua kali. Gunakan semua batasan yang dinamai secara eksplisit (jangan gunakan DEFAULT), atau gunakan semua nama yang ditentukan sistem (gunakan DEFAULT).
  3. Edit file model.xml secara manual dan ganti nama constraint yang menyebabkan error menjadi nama yang unik. Opsi ini harus dilakukan hanya jika diarahkan oleh dukungan Microsoft dan menimbulkan risiko .bacpac kerusakan.

Pengecualian stack overflow

Skrip T-SQL besar dengan banyak pernyataan bersarang dapat menyebabkan pengecualian stack overflow yang sporadis atau persisten. Ketika kondisi ini terjadi, pesan kesalahan menyertakan teks Stack overflow dan jejak tumpukan:

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)

Parameter untuk SqlPackage tersedia di semua perintah, /ThreadMaxStackSize:, yang menentukan ukuran tumpukan maksimum untuk utas yang menjalankan proses SqlPackage. Nilai default ditentukan oleh versi .NET yang menjalankan SqlPackage. Menetapkan nilai besar dapat memengaruhi performa keseluruhan SqlPackage. Namun, meningkatkan nilai ini mungkin dapat menyelesaikan pengecualian stack overflow yang disebabkan oleh pernyataan bersarang. Refaktor kode T-SQL untuk menghindari pengecualian stack overflow kapan pun memungkinkan. Jika Anda tidak dapat melakukan refactor, gunakan parameter ini /ThreadMaxStackSize: sebagai solusi sementara.

Saat Anda menggunakan parameter /ThreadMaxStackSize:, sesuaikan operasi yang berulang ke nilai serendah mungkin yang dapat mengatasi eksepsi stack overflow jika Anda melihat adanya dampak pada kinerja. Nilai parameter adalah dalam megabyte (MB). Misalnya, Anda dapat menguji nilai seperti 10 dan 100.

Saran tindakan impor

Untuk impor yang berisi tabel besar atau tabel dengan banyak indeks, menggunakan /p:RebuildIndexesOfflineForDataPhase=True atau /p:DisableIndexesForDataPhase=False dapat meningkatkan kinerja. Properti ini mengubah operasi pembangunan ulang indeks agar dilakukan secara offline atau tidak dilakukan. Anda dapat menggunakan properti ini dan properti lain untuk menyetel operasi Impor SqlPackage .

Indeks dinonaktifkan setelah impor

Untuk memuat data secara efisien, impor menonaktifkan indeks yang tidak terklaster sebelum fase data dan membangunnya kembali setelahnya (perilaku default /p:DisableIndexesForDataPhase=True ). Jika impor terhenti atau gagal setelah data dimuat tetapi sebelum proses pembangunan ulang selesai, satu atau lebih indeks nonklaster dapat tetap dinonaktifkan. Indeks yang dinonaktifkan tetap ada di metadata, tetapi pengoptimal kueri mengabaikannya, yang dapat menyebabkan kueri menjadi lambat setelah impor yang tampaknya berhasil.

Untuk menemukan indeks yang dinonaktifkan, periksa is_disabled kolom di tampilan katalog sys.indexes :

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;

Untuk mengaktifkan kembali indeks yang dinonaktifkan, buat ulang indeks tersebut dengan ALTER INDEX. Gunakan ALTER INDEX ALL ... REBUILD untuk mengaktifkan semua indeks yang dinonaktifkan pada sebuah tabel:

ALTER INDEX ALL ON <schema>.<table> REBUILD;

Untuk informasi lebih lanjut, lihat Aktifkan indeks dan batasan.

Tips tindakan ekspor

Agar ekspor konsisten secara transaksi, pastikan tidak ada aktivitas penulisan yang terjadi selama ekspor, atau Anda mengekspor dari salinan database yang konsisten secara transaksi . Jika Anda menerima kesalahan terkait batasan foreign key selama impor, ekspor tersebut mungkin tidak konsisten secara transaksional akibat adanya rekaman yang disisipkan atau diperbarui selama proses ekspor.

Performa selama ekspor

Penyebab umum penurunan performa selama ekspor adalah referensi objek yang belum terselesaikan. Masalah ini menyebabkan SqlPackage mencoba menyelesaikan objek tersebut beberapa kali. Misalnya, sebuah tampilan didefinisikan yang merujuk pada sebuah tabel tetapi tabel tersebut tidak lagi ada di database. Jika referensi yang belum terselesaikan muncul di log ekspor, pertimbangkan untuk memperbaiki skema database untuk meningkatkan performa ekspor.

Selama proses ekspor, data tabel dikompresi dalam file bacpac. Mengatur /p:CompressionOption ke Fast, SuperFast, atau NotCompressed mungkin meningkatkan kecepatan proses ekspor sambil mengurangi kompresi file bacpac output.

Untuk mendapatkan skema database dan data saat melewati validasi skema, lakukan Ekspor dengan properti /p:VerifyExtraction=False. Ekspor yang tidak valid mungkin dihasilkan yang tidak dapat diimpor.

Ruang disk selama ekspor

Dalam skenario di mana ruang disk OS terbatas dan habis selama ekspor, gunakan /p:TempDirectoryForTableData untuk buffer data agar bisa diekspor ke disk alternatif. Ruang yang diperlukan untuk tindakan ini mungkin besar dan relatif terhadap ukuran penuh database. Anda dapat mengatur operasi Ekspor SqlPackage dengan mengatur properti ini dan properti lainnya.

Azure SQL Database

Tips berikut khusus untuk menjalankan impor atau ekspor terhadap Azure SQL Database dari komputer virtual Azure (VM):

  • Gunakan database tingkat Business Critical atau Premium untuk performa terbaik.
  • Gunakan penyimpanan SSD pada VM.
  • Pastikan ada cukup ruang untuk membuka resleting tas punggung.
  • Jalankan SqlPackage dari VM di wilayah yang sama dengan database.
  • Aktifkan jaringan terakselerasi di VM.

Untuk informasi selengkapnya tentang penggunaan skrip PowerShell untuk mengumpulkan rincian tentang operasi impor, lihat Pelajaran yang Dipetik #211: Memantau Proses Impor SQLPackage.

Sumber daya lainnya

Blog Dukungan Azure Database berisi banyak artikel tentang pemecahan masalah dan penyetelan performa untuk Azure SQL Database, termasuk beberapa artikel di SqlPackage.

Beberapa artikel yang paling relevan meliputi: