Bagaimana seseorang menyelidiki kinerja pernyataan BULK INSERT?

12

Saya terutama seorang pengembang .NET yang menggunakan Entity Framework ORM. Namun, karena saya tidak ingin gagal dalam menggunakan ORM , saya mencoba memahami apa yang terjadi dalam lapisan data (database). Pada dasarnya, selama pengembangan saya memulai profiler dan memeriksa apa yang menghasilkan beberapa bagian dari kode dalam hal permintaan.

Jika saya melihat sesuatu yang sangat rumit (ORM dapat menghasilkan pertanyaan yang mengerikan bahkan dari pernyataan LINQ yang agak sederhana, jika tidak ditulis dengan hati-hati) dan / atau berat (durasi, CPU, halaman berbunyi), saya membawanya dalam SSMS dan memeriksa rencana pelaksanaannya.

Ini berfungsi dengan baik untuk tingkat pengetahuan basis data saya. Namun, BULK INSERT tampaknya menjadi makhluk khusus, karena sepertinya tidak menghasilkan SHOWPLAN .

Saya akan mencoba menggambarkan contoh yang sangat sederhana:

Definisi tabel

CREATE TABLE dbo.ImportingSystemFileLoadInfo
(
    ImportingSystemFileLoadInfoId INT NOT NULL IDENTITY(1, 1) CONSTRAINT PK_ImportingSystemFileLoadInfo PRIMARY KEY CLUSTERED,
    EnvironmentId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo REFERENCES dbo.Environment,
    ImportingSystemId INT NOT NULL CONSTRAINT FK_ImportingSystemFileLoadInfo_ImportingSystem REFERENCES dbo.ImportingSystem,
    FileName NVARCHAR(64) NOT NULL,
FileImportTime DATETIME2 NOT NULL,
    CONSTRAINT UQ_ImportingSystemImportInfo_EnvXIs_TableName UNIQUE (EnvironmentId, ImportingSystemId, FileName, FileImportTime)
)

Catatan: tidak ada indeks lain yang didefinisikan pada tabel

Sisipan massal (yang saya tangkap di profiler, hanya satu batch)

insert bulk [dbo].[ImportingSystemFileLoadInfo] ([EnvironmentId] Int, [ImportingSystemId] Int, [FileName] NVarChar(64) COLLATE Latin1_General_CI_AS, [FileImportTime] DateTime2(7))

Metrik

  • 695 item dimasukkan
  • CPU = 31
  • Dibaca = 4271
  • Menulis = 24
  • Durasi = 154
  • Jumlah tabel total = 11500

Untuk aplikasi saya, tidak apa-apa, walaupun bacaannya agak besar (saya tahu sedikit tentang SQL Server internal, jadi saya membandingkan dengan ukuran halaman 8K dan informasi catatan kecil yang saya miliki)

Pertanyaan: bagaimana saya bisa menyelidiki jika BULK INSERT ini dapat dioptimalkan? Atau tidak masuk akal, karena ini bisa dibilang cara tercepat untuk mendorong data besar dari aplikasi klien ke SQL Server?

Alexei
sumber

Jawaban:

14

Sejauh yang saya tahu Anda dapat mengoptimalkan insert massal dengan cara yang sangat mirip bahwa Anda akan mengoptimalkan insert reguler. Biasanya, rencana kueri untuk penyisipan sederhana tidak terlalu informatif sehingga jangan khawatir tentang tidak memiliki rencana. Saya akan membahas beberapa cara untuk mengoptimalkan sisipan tetapi kebanyakan dari mereka mungkin tidak berlaku untuk sisipan yang Anda tentukan dalam pertanyaan. Namun, mereka bisa membantu jika di masa depan Anda perlu memuat data dalam jumlah yang lebih besar.

1. Masukkan data dalam urutan kunci pengelompokan

SQL Server akan sering mengurutkan data sebelum memasukkannya ke dalam tabel dengan indeks berkerumun. Untuk beberapa tabel dan aplikasi Anda dapat meningkatkan kinerja dengan menyortir data dalam file datar dan membiarkan SQL Server tahu bahwa data diurutkan melalui ORDERargumen BULK INSERT:

ORDER ({kolom [ASC | DESC]} [, ... n])

Menentukan bagaimana data dalam file data diurutkan. Kinerja impor massal ditingkatkan jika data yang diimpor disortir menurut indeks berkerumun di tabel, jika ada.

Karena Anda menggunakan IDENTITYkolom sebagai kunci berkerumun, Anda tidak perlu khawatir tentang ini.

2. Gunakan TABLOCKjika memungkinkan

Jika Anda dijamin hanya memiliki satu sesi memasukkan data ke tabel Anda, Anda dapat menentukan TABLOCKargumen untuk BULK INSERT. Ini dapat mengurangi pertikaian kunci dan dapat menyebabkan minimal logging di beberapa skenario. Namun, Anda memasukkan ke dalam tabel dengan indeks berkerumun yang sudah berisi data sehingga Anda tidak akan mendapatkan penebangan minimal tanpa jejak bendera 610 yang disebutkan kemudian dalam jawaban ini.

Jika TABLOCKtidak memungkinkan, karena Anda tidak dapat mengubah kode , tidak semua harapan hilang. Pertimbangkan menggunakan sp_table_option:

EXEC [sys].[sp_tableoption]
    @TableNamePattern = N'dbo.BulkLoadTable' ,
    @OptionName = 'table lock on bulk load' , 
    @OptionValue = 'ON'

Pilihan lain adalah mengaktifkan jejak flag 715 .

3. Gunakan ukuran batch yang sesuai

Terkadang Anda dapat menyetel sisipan dengan mengubah ukuran bets.

ROWS_PER_BATCH = rows_per_batch

Menunjukkan perkiraan jumlah baris data dalam file data.

Secara default, semua data dalam file data dikirim ke server sebagai satu transaksi, dan jumlah baris dalam batch tidak diketahui oleh optimizer kueri. Jika Anda menentukan ROWS_PER_BATCH (dengan nilai> 0) server menggunakan nilai ini untuk mengoptimalkan operasi impor massal. Nilai yang ditentukan untuk ROWS_PER_BATCH harus kira-kira sama dengan jumlah baris aktual. Untuk informasi tentang pertimbangan kinerja, lihat "Keterangan," nanti dalam topik ini.

Berikut ini kutipan dari artikel selanjutnya:

Jika jumlah halaman yang akan disiram dalam satu batch melebihi ambang internal, pemindaian penuh dari kumpulan buffer mungkin terjadi untuk mengidentifikasi halaman mana yang akan disiram ketika batch melakukan. Pemindaian lengkap ini dapat merusak kinerja impor massal. Kasus kemungkinan melebihi ambang internal terjadi ketika kumpulan buffer besar dikombinasikan dengan subsistem I / O yang lambat. Untuk menghindari buffer overflows pada mesin besar, jangan gunakan petunjuk TABLOCK (yang akan menghapus optimasi massal) atau menggunakan ukuran batch yang lebih kecil (yang menjaga optimasi bulk).

Karena komputer berbeda-beda, kami sarankan Anda menguji berbagai ukuran bets dengan beban data Anda untuk mengetahui mana yang paling cocok untuk Anda.

Secara pribadi saya hanya akan memasukkan semua 695 baris dalam satu batch. Tuning ukuran batch dapat membuat perbedaan besar saat memasukkan banyak data.

4. Pastikan Anda membutuhkan IDENTITYkolom

Saya tidak tahu apa-apa tentang model atau persyaratan data Anda, tetapi jangan jatuh ke dalam perangkap menambahkan IDENTITYkolom ke setiap tabel. Aaron Bertrand memiliki artikel tentang kebiasaan buruk ini untuk ditendang: meletakkan kolom IDENTITAS di setiap meja . Untuk lebih jelasnya, saya tidak mengatakan bahwa Anda harus menghapus IDENTITYkolom dari tabel ini. Namun, jika Anda menentukan bahwa IDENTITYkolom tidak diperlukan dan menghapusnya yang dapat meningkatkan kinerja penyisipan.

5. Nonaktifkan indeks atau batasan

Jika Anda memuat sejumlah besar data ke dalam tabel dibandingkan dengan apa yang sudah Anda miliki maka mungkin lebih cepat untuk menonaktifkan indeks atau kendala sebelum memuat dan untuk mengaktifkannya setelah memuat. Untuk sejumlah besar data, biasanya lebih tidak efisien untuk SQL Server untuk membangun indeks sekaligus daripada data dimuat ke dalam tabel. Sepertinya Anda memasukkan 695 baris ke tabel dengan 11500 baris, jadi saya tidak akan merekomendasikan teknik ini.

6. Pertimbangkan TF 610

Trace Flag 610 memungkinkan penebangan minimal dalam beberapa skenario tambahan. Untuk tabel Anda dengan IDENTITYkunci berkerumun, Anda akan mendapatkan pendataan minimal untuk setiap halaman data baru selama model pemulihan Anda sederhana atau sebagian besar dicatat. Saya percaya fitur ini tidak aktif secara default karena dapat menurunkan kinerja pada beberapa sistem. Anda perlu menguji dengan cermat sebelum mengaktifkan tanda jejak ini. Referensi Microsoft yang direkomendasikan masih tampak sebagai Panduan Kinerja Pemuatan Data

Dampak I / O dari Penebangan Minimal di Bawah Bendera Jejak 610

Ketika Anda melakukan transaksi pemuatan massal yang dicatat minimal, semua halaman yang dimuat harus dibuang ke disk sebelum komit selesai. Halaman memerah yang tidak tertangkap oleh operasi pos pemeriksaan sebelumnya dapat membuat banyak I / O acak. Bandingkan ini dengan operasi yang sepenuhnya dicatat, yang menciptakan I / O berurutan pada log dan sebagai gantinya tidak memerlukan halaman yang dimuat untuk dibuang ke disk pada waktu yang ditentukan.

Jika skenario beban Anda adalah operasi penyisipan kecil pada btrees yang tidak melewati batas pos pemeriksaan, dan Anda memiliki sistem I / O yang lambat, menggunakan pencatatan minimum sebenarnya dapat memperlambat kecepatan penyisipan.

Sejauh yang saya tahu ini tidak ada hubungannya dengan jejak bendera 610, melainkan dengan logging minimal. Saya percaya kutipan sebelumnya tentang ROWS_PER_BATCHpenyetelan mendapatkan konsep yang sama.

Sebagai kesimpulan, mungkin tidak banyak yang dapat Anda lakukan untuk menyetel lagu Anda BULK INSERT. Saya tidak akan khawatir tentang hitungan baca yang Anda amati dengan sisipan Anda. SQL Server akan melaporkan pembacaan kapan saja Anda memasukkan data. Pertimbangkan yang berikut ini sangat sederhana INSERT:

DROP TABLE IF EXISTS X_TABLE;

CREATE TABLE X_TABLE (
VAL VARCHAR(1000) NOT NULL
);

SET STATISTICS IO, TIME ON;

INSERT INTO X_TABLE WITH (TABLOCK)
SELECT REPLICATE('Z', 1000)
FROM dbo.GetNums(10000); -- generate 10000 rows

Output dari SET STATISTICS IO, TIME ON:

Tabel 'X_TABLE'. Pindai hitungan 0, bacaan logis 11428

Saya memiliki 11.428 yang dilaporkan dibaca tetapi itu bukan informasi yang bisa ditindaklanjuti. Terkadang jumlah pembacaan yang dilaporkan dapat dikurangi dengan pencatatan minimum, tetapi tentu saja perbedaannya tidak dapat langsung diterjemahkan ke dalam peningkatan kinerja.

Joe Obbish
sumber
12

Saya akan mulai menjawab pertanyaan ini, dengan maksud untuk terus memperbarui jawaban ini ketika saya membangun basis pengetahuan trik. Semoga orang lain menemukan ini dan membantu saya meningkatkan pengetahuan saya sendiri dalam prosesnya.

  1. Periksa Dudukan: Apakah firewall Anda melakukan pemeriksaan paket yang mendalam dan stateful? Anda tidak akan menemukan banyak hal di Internet tentang ini, tetapi jika insert massal Anda sekitar 10x lebih lambat dari yang seharusnya, kemungkinan Anda memiliki alat keamanan yang melakukan inspeksi paket mendalam Level 3-7 dan memeriksa "Generic SQL Injection Prevention ".

  2. Ukur ukuran data yang Anda rencanakan untuk dimasukkan secara massal, dalam byte, per batch. Dan periksa apakah Anda menyimpan data LOB, karena itu adalah halaman terpisah untuk mengambil dan menulis operasi.

    Beberapa alasan mengapa Anda harus melakukannya dengan cara ini:

    Sebuah. Dalam AWS, IOPS Penyimpanan Blok Elastis dipecah menjadi byte, bukan baris.

    1. Lihat Performa Volume EBS Amazon di Mesin Virtual Linux »Karakteristik dan Pengawasan I / O untuk penjelasan tentang apa itu unit IBS EBS
    2. Khususnya, volume General Purpose SSD (gp2) memiliki konsep "I / O Credits and Burst Performance" dan itu adalah umum untuk pemrosesan ETL yang berat untuk menghabiskan kredit saldo meledak. Durasi burst Anda diukur dalam byte, bukan baris SQL Server :)

    b. Sementara sebagian besar perpustakaan atau whitepapers menguji berdasarkan jumlah baris, itu sebenarnya jumlah halaman yang dapat ditulis untuk masalah itu, dan, untuk menghitungnya, Anda perlu tahu berapa banyak byte per baris dan ukuran halaman Anda (biasanya 8KB , tetapi selalu periksa kembali apakah Anda mewarisi sistem dari orang lain.)

    SELECT *
    FROM 
    sys.dm_db_index_physical_stats(DB_ID(),OBJECT_ID(N'YourTable'), NULL, NULL, 'DETAILED')

    Perhatikan avg_record_size_in_bytes dan page_count.

    c. Seperti yang dijelaskan oleh Paul White di https://sqlperformance.com/2019/05/sql-performance/minimal-logging-insert-select-heap , "Untuk mengaktifkan minimal logging INSERT...SELECT, SQL Server harus mengharapkan lebih dari 250 baris dengan ukuran total setidaknya satu tingkat (8 halaman). "

  3. Jika Anda memiliki indeks dengan kendala pemeriksaan, atau kendala unik, gunakan SET STATISTICS IO ONdan SET STATISTICS TIME ON(atau SQL Server Profiler atau SQL Server Extended Events) untuk mengambil informasi seperti apakah insert massal Anda memiliki operasi baca. Baca operasi disebabkan oleh mesin database SQL Server memastikan kendala integritas lulus.

  4. Coba buat basis data uji tempat PRIMARYFILEGROUP dipasang pada drive RAM. Ini harus sedikit lebih cepat daripada SSD tetapi juga menghilangkan pertanyaan, apakah RAID Controller Anda mungkin menambahkan overhead. Pada 2018, seharusnya tidak, tetapi dengan membuat beberapa garis dasar diferensial seperti ini, Anda bisa mendapatkan gambaran umum tentang berapa banyak overhead yang ditambahkan perangkat keras Anda.

  5. Juga meletakkan file sumber pada drive RAM juga.

    Menempatkan file sumber pada Drive RAM akan mengesampingkan masalah pertikaian jika Anda membaca file sumber dari drive yang sama dengan FILEGROUP server database Anda.

  6. Verifikasi bahwa Anda telah memformat hard drive menggunakan ekstensi 64KB.

  7. Gunakan UserBenchmark.com dan patok SSD Anda. Ini akan:

    1. Tambahkan lebih banyak pengetahuan kepada penggemar kinerja lain tentang kinerja apa yang diharapkan dari perangkat
    2. Membantu Anda mengetahui apakah kinerja drive Anda memiliki performa yang buruk dengan drive yang sama persis
    3. Membantu Anda mengetahui apakah kinerja drive Anda kurang menjalankan drive lain dalam kategori yang sama (SSD, HDD, dll.)
  8. Jika Anda memanggil "INSERT BULK" dari C # melalui Extensions Framework Entity, maka pastikan Anda "menghangatkan" JIT terlebih dahulu dan "membuang" beberapa hasil pertama.

  9. Coba buat Penghitung Kinerja untuk program Anda. Dengan .NET, Anda dapat menggunakan benchmark.NET dan secara otomatis profil profil sekelompok metrik dasar. Anda kemudian dapat BERBAGI upaya profiler Anda dengan komunitas open source, dan melihat apakah orang yang menjalankan perangkat keras yang berbeda melaporkan metrik yang sama (yaitu dari titik saya sebelumnya tentang menggunakan UserBenchmark.com untuk membandingkan).

  10. Coba gunakan pipa bernama dan jalankan sebagai localhost.

  11. Jika Anda menargetkan SQL Server dan menggunakan .NET Core, pertimbangkan untuk memutar Linux dengan SQL Server Std Edition - harganya kurang dari satu dolar per jam bahkan untuk perangkat keras yang serius. Keuntungan utama untuk mencoba kode yang sama dengan perangkat keras yang sama dengan OS yang berbeda adalah untuk melihat apakah tumpukan TCP / IP kernel OS menyebabkan masalah.

  12. Gunakan Query Diagnostic SQL Server Glen Barry untuk mengukur latensi drive untuk drive yang menyimpan FILEGROUP dari tabel database Anda.

    Sebuah. Pastikan untuk mengukur sebelum ujian Anda, dan setelah ujian Anda. "Sebelum pengujian" hanya memberi tahu Anda apakah Anda memiliki karakteristik IO yang mengerikan sebagai garis dasar.

    b. Untuk mengukur "selama pengujian", Anda benar-benar perlu menggunakan Penghitung Kinerja PerfMon.

    Mengapa? Karena sebagian besar server database menggunakan semacam penyimpanan jaringan terpasang (NAS). Di cloud, di AWS, Elastic Block Storage hanya itu. Anda dapat diikat oleh IOPS dari solusi volume / NAS EBS Anda.

  13. Gunakan beberapa alat untuk mengukur statistik tunggu. Red Gate SQL Monitor , SolarWinds Database Performance Analyzer, atau bahkan Query Diagnostic SQL Server Glen Barry, atau permintaan Statistik Tunggu Paul Randal .

    Sebuah. Jenis menunggu yang paling umum adalah Memory / CPU, WRITELOG, PAGEIOLATCH_EX, dan ASYNC_NETWORK_IO .

    b. Anda mungkin dikenakan jenis tunggu tambahan jika Anda menjalankan Grup yang Tersedia.

  14. Ukur efek dari beberapa INSERT BULKperintah sekaligus yang TABLOCKdinonaktifkan (TABLOCK kemungkinan akan memaksa serialisasi perintah INSERT BULK). Kemacetan Anda bisa menunggu INSERT BULKsampai selesai; Anda harus mencoba mengantre sebanyak mungkin dari tugas-tugas ini seperti yang dapat ditangani oleh model data fisik server database Anda.

  15. Pertimbangkan mempartisi meja Anda. Sebagai contoh khusus: jika tabel database Anda hanya append, Andrew Novick menyarankan untuk membuat "HARI INI" FILEGROUPdan mempartisi menjadi setidaknya dua filegroup, TODAY dan BEFORE_TODAY. Dengan cara ini, jika INSERT BULKdata Anda hanya data untuk hari ini, Anda bisa memfilter pada bidang CreatedOn untuk memaksa semua sisipan untuk menekan satu FILEGROUP, dan dengan demikian mengurangi pemblokiran saat menggunakan TABLOCK. Teknik ini dijelaskan secara lebih rinci dalam Microsoft Whitepaper: Tabel Partisi dan Strategi Indeks Menggunakan SQL Server 2008

  16. Jika Anda menggunakan indeks toko kolom, matikan TABLOCKdan muat data dalam 102,400 baris Ukuran Batch. Anda kemudian dapat memuat semua data Anda secara paralel langsung ke rowgroup kolomstore. Saran ini (dan rasional yang didokumentasikan) berasal dari indeks Microsoft's Columnstore - Panduan pemuatan data :

    Pemuatan massal memiliki optimisasi kinerja internal ini:

    Muatan paralel: Anda dapat memiliki beberapa beban massal bersamaan (insert bcp atau bulk) yang masing-masing memuat file data terpisah. Tidak seperti baris massal memuat ke SQL Server, Anda tidak perlu menentukan TABLOCKkarena setiap utas impor massal akan memuat data secara eksklusif ke dalam grup baris terpisah (barisgroup terkompresi atau delta) dengan kunci eksklusif di atasnya. Menggunakan TABLOCKakan memaksa kunci eksklusif di atas meja dan Anda tidak akan dapat mengimpor data secara paralel.

    Minimal logging:Beban massal menggunakan minimal logging pada data yang langsung ke grup baris terkompresi. Data apa pun yang masuk ke grup baris delta sepenuhnya dicatat. Ini termasuk ukuran batch yang kurang dari 102.400 baris. Namun, dengan pemuatan massal, tujuannya adalah untuk sebagian besar data memintas grup baris delta.

    Mengunci Pengoptimalan: Saat memuat ke grup baris terkompresi, kunci X pada grup baris diperoleh. Namun, ketika memuat massal ke delta rowgroup, kunci X diperoleh di rowgroup tetapi SQL Server masih mengunci PAGE / EXTENT karena kunci rowgroup X bukan bagian dari hierarki penguncian.

  17. Pada SQL Server 2016, tidak perlu lagi mengaktifkan jejak flag 610 untuk masuk minimum ke tabel yang diindeks . Mengutip insinyur Microsoft Parikshit Savjani ( penekanan milik saya ):

    Salah satu tujuan desain SQL Server 2016 adalah untuk meningkatkan kinerja dan skalabilitas mesin di luar kotak untuk membuatnya berjalan lebih cepat tanpa perlu tombol atau jejak bendera untuk pelanggan. Sebagai bagian dari perbaikan ini, salah satu perangkat tambahan yang dibuat dalam kode mesin SQL Server menghidupkan konteks beban massal (juga disebut sebagai memasukkan cepat atau konteks memuat cepat) dan penebangan minimal secara default ketika melakukan operasi beban massal pada database dengan sederhana atau model pemulihan log massal Jika Anda tidak terbiasa dengan minimal logging, saya akan sangat menyarankan membaca posting blog ini dari Sunil Agrawal di mana dia menjelaskan bagaimana minimal logging bekerja di SQL Server. Agar insert massal dapat dicatat secara minimal, masih perlu memenuhi persyaratan prasyarat yang didokumentasikan di sini.

    Sebagai bagian dari peningkatan ini di SQL Server 2016, Anda tidak perlu lagi mengaktifkan jejak flag 610 untuk masuk minimum ke dalam tabel yang diindeksdan bergabung dengan beberapa bendera jejak lainnya (1118, 1117, 1236, 8048) untuk menjadi bagian dari sejarah. Dalam SQL Server 2016, ketika operasi beban massal menyebabkan halaman baru dialokasikan, semua baris secara berurutan mengisi halaman baru yang minimal dicatat jika semua prasyarat lain untuk logging minimal yang dibahas sebelumnya terpenuhi. Baris yang dimasukkan ke halaman yang ada (tidak ada alokasi halaman baru) untuk mempertahankan urutan indeks masih sepenuhnya dicatat, demikian juga baris yang dipindahkan sebagai hasil dari pemisahan halaman selama pemuatan. Penting juga untuk mengaktifkan ALLOW_PAGE_LOCKS AKTIF untuk indeks (yang AKTIF secara default) agar operasi logging minimal dapat berfungsi karena kunci halaman diperoleh selama alokasi dan dengan demikian hanya alokasi halaman atau luas yang dicatat.

  18. Jika Anda menggunakan SqlBulkCopy di C # atau EntityFramework.Extensions (yang menggunakan SqlBulkCopy di bawah tenda), kemudian periksa konfigurasi build Anda. Apakah Anda menjalankan tes dalam mode Rilis? Apakah Arsitektur Target disetel ke Any CPU / x64 / x86?

  19. Pertimbangkan menggunakan sp_who2 untuk melihat apakah transaksi INSERT BULK DITANGGUHKAN. Ini dapat DITANGGUHKAN karena diblokir oleh spid lain. Pertimbangkan membaca Cara Meminimalkan Pemblokiran SQL Server . Anda juga dapat menggunakan sp_WhoIsActive dari Adam Machanic, tetapi sp_who2 akan memberi Anda informasi dasar yang Anda butuhkan.

  20. Anda mungkin hanya memiliki disk I / O yang buruk. Jika Anda melakukan penyisipan massal dan penggunaan disk Anda tidak mencapai 100%, dan macet sekitar 2%, maka Anda mungkin memiliki firmware yang buruk, atau perangkat I / O yang rusak. (Ini terjadi pada rekan kerja saya.) Gunakan [SSD UserBenchmark] untuk dibandingkan dengan orang lain untuk kinerja perangkat keras, terutama jika Anda dapat meniru kelambatan pada mesin dev lokal Anda. (Saya menempatkan ini terakhir dalam daftar karena sebagian besar perusahaan tidak mengizinkan pengembang untuk menjalankan database pada mesin lokal mereka karena risiko IP.)

  21. Jika tabel Anda menggunakan kompresi, Anda dapat mencoba menjalankan beberapa sesi, dan di setiap sesi, mulailah dengan menggunakan transaksi yang ada dan jalankan ini sebelum perintah SqlBulkCopy:

    ALTER SERVER CONFIGURATION SET PROSES AFFINITY CPU = AUTO;

  22. Untuk Pemuatan Berkelanjutan, satu aliran ide, pertama kali diuraikan dalam whitepaper Microsoft, Tabel Partisi dan Strategi Indeks Menggunakan SQL Server 2008 :

    Pemuatan berkelanjutan

    Dalam skenario OLTP, data baru mungkin datang terus menerus. Jika pengguna juga menanyakan partisi terbaru, memasukkan data secara terus-menerus dapat menyebabkan pemblokiran: Permintaan pengguna dapat memblokir sisipan, dan juga, sisipan dapat memblokir kueri pengguna.

    Kontensi pada tabel atau partisi pemuatan dapat dikurangi dengan menggunakan isolasi snapshot — khususnya, READ COMMITTED SNAPSHOTlevel isolasi. Di bawah READ COMMITTED SNAPSHOTisolasi, menyisipkan ke dalam tabel tidak menyebabkan aktivitas di toko versi tempdb , sehingga overhead tempdb minimal untuk menyisipkan, tetapi tidak ada kunci bersama yang akan diambil oleh kueri pengguna pada partisi yang sama.

    Dalam kasus lain, ketika data dimasukkan ke dalam tabel dipartisi secara terus-menerus dengan kecepatan tinggi, Anda mungkin masih dapat melakukan tahapan data untuk periode waktu yang pendek dalam tabel pementasan dan kemudian memasukkan data itu ke partisi terbaru berulang kali hingga jendela untuk partisi saat ini lewat dan data kemudian dimasukkan ke partisi berikutnya. Misalnya, anggap Anda memiliki dua tabel pementasan yang masing-masing menerima nilai data 30 detik, secara bergantian: satu tabel untuk paruh pertama satu menit, tabel kedua untuk paruh kedua satu menit. Prosedur yang tersimpan sisipan menentukan setengah dari saat memasukkan saat ini, dan kemudian memasukkan ke dalam tabel staging pertama. Ketika 30 detik habis, prosedur memasukkan menentukan harus memasukkan ke dalam tabel pementasan kedua. Prosedur tersimpan lainnya kemudian memuat data dari tabel pementasan pertama ke partisi tabel yang terbaru, dan kemudian memotong tabel pementasan pertama. Setelah 30 detik berikutnya, prosedur tersimpan yang sama memasukkan data dari prosedur tersimpan kedua dan memasukkannya ke partisi saat ini, dan kemudian memotong tabel pementasan kedua.

  23. Panduan Kinerja Pemuatan Data oleh Microsoft CAT Team

  24. Pastikan statistik Anda terbaru. Gunakan FULLSCAN jika Anda bisa setelah setiap pembuatan indeks.

  25. Tuning Kinerja SAN dengan SQLIO dan juga pastikan jika Anda menggunakan disk mekanis agar partisi disk Anda sejajar. Lihat Praktik Terbaik Penyelarasan Disk Microsoft .

  26. COLUMNSTORE INSERT/ UPDATEkinerja

John Zabroski
sumber
2

Bacaan cenderung menjadi kendala unik & FK yang diperiksa selama penyisipan - Anda mungkin mendapatkan peningkatan kecepatan jika Anda dapat menonaktifkan / menjatuhkannya selama penyisipan & mengaktifkan / membuatnya kembali setelah itu. Anda harus menguji apakah ini membuatnya lebih lambat secara keseluruhan dibandingkan membuatnya tetap aktif. Ini juga mungkin bukan ide yang baik jika proses lain menulis ke tabel yang sama secara bersamaan. - Gareth Lyons

Menurut T&J kunci Asing menjadi tidak dipercaya setelah memasukkan massal , kendala FK menjadi tidak dipercaya setelah BULK INSERTtanpa CHECK_CONSTRAINTSopsi (kasus saya karena saya berakhir dengan kendala tidak dipercaya). Tidak jelas, tetapi tidak masuk akal untuk memeriksa mereka dan masih membuat mereka tidak dipercaya. Namun, PK dan UNIK masih akan diperiksa (lihat BULK INSERT (Transact-SQL) ). - Alexei

pengguna126897
sumber