Apa cara tercepat untuk memasukkan banyak baris?


27

Saya memiliki database tempat saya memuat file ke dalam tabel pementasan, dari tabel pementasan ini saya memiliki 1-2 bergabung untuk menyelesaikan beberapa kunci asing dan kemudian memasukkan baris ini ke dalam tabel akhir (yang memiliki satu partisi per bulan). Saya memiliki sekitar 3,4 miliar baris selama tiga bulan data.

Apa cara tercepat untuk mendapatkan baris ini dari pementasan ke meja final? SSIS Data Flow Task (yang menggunakan view sebagai sumber dan memiliki fast load aktif) atau perintah Insert INTO SELECT ....? Saya mencoba Data Flow Task dan bisa mendapatkan sekitar 1 miliar baris dalam waktu sekitar 5 jam (8 core / 192 GB RAM di server) yang terasa sangat lambat bagi saya.


1
Apakah partisi pada filegroup terpisah (dan ada pada filegroup pada disk fisik yang berbeda)?
Aaron Bertrand

3
Sumber yang sangat bagus Panduan Kinerja Memuat Data . Ini membahas banyak optimasi kinerja yang dapat Anda lakukan misalnya Mengaktifkan TF610 , Menggunakan BCP OUT / IN, SSIS dll. Anda hanya perlu mengikuti rekomendasi dan mengujinya di lingkungan Anda.
Kin Shah

@ Harun ya, per bulan satu filegroup, 12 san lun terpasang jadi semua jan pergi satu lun dll. Tidak yakin berapa banyak disk per lun tetapi harus banyak.
nojetlag

Ya saya benar-benar berarti "set disk" dan mungkin bisa disebutkan pengendali juga, yang bisa jenuh.
Aaron Bertrand

@ Kin telah melihat panduan ini tetapi tampaknya sudah ketinggalan zaman, "Tujuan SQL Server adalah cara tercepat untuk memuat data massal dari aliran data Layanan Integrasi ke SQL Server. Tujuan ini mendukung semua opsi pemuatan massal SQL Server - kecuali ROWS_PER_BATCH . " dan dalam SSIS 2012 mereka merekomendasikan tujuan OLE DB untuk kinerja yang lebih baik.
nojetlag

Jawaban:


25

Satu pendekatan umum:

  1. Nonaktifkan / jatuhkan indeks / batasan pada tabel target.
  2. INSERT dbo.[Target] WITH (TABLOCKX) SELECT ...
  3. Dengan kredit ke JNK tentu saja, Anda dapat melakukan hal di atas dalam kumpulan nbaris, yang dapat mengurangi ketegangan pada log transaksi, dan tentu saja berarti bahwa jika beberapa batch gagal, Anda hanya perlu memulai dari batch itu. Saya membuat blog tentang ini (sementara mengacu pada penghapusan, konsep dasar yang sama berlaku) di sini: http://www.sqlperformance.com/2013/03/io-subsystem/chunk-deletes
  4. Aktifkan kembali / buat ulang indeks / batasan pada tabel target (dan mungkin Anda dapat menunda beberapa dari mereka, jika mereka tidak diperlukan untuk semua operasi, dan lebih penting untuk mendapatkan basis data online dengan cepat).

Jika partisi Anda bersifat fisik dan bukan hanya logis, Anda dapat memperoleh waktu dengan memiliki proses yang berbeda mengisi partisi yang berbeda secara bersamaan (tentu saja ini berarti Anda tidak dapat menggunakan TABLOCK/ TABLOCKX). Ini mengasumsikan bahwa sumber juga cocok untuk memilih beberapa proses tanpa tumpang tindih / mengunci dll, dan membuat sisi operasi lebih lambat (petunjuk: buat indeks berkerumun pada sumber yang sesuai dengan skema partisi pada tujuan).

Anda juga dapat mempertimbangkan sesuatu yang jauh lebih primitif, seperti BCP OUT/BCP IN .

Saya tidak tahu bahwa saya akan melompat ke SSIS untuk membantu ini. Mungkin ada beberapa efisiensi di sana, tetapi saya tidak tahu bahwa upaya itu membenarkan penghematan.


2
Jangan menjatuhkan indeks secara buta (khususnya indeks berkerumun) jika data Anda tidak diurutkan. Menjatuhkan indeks dan berharap untuk membuat ulang indeks berkerumun dapat menjadi kesalahan besar karena dapat menghabiskan ruang disk besar ditambah waktu yang sangat lama. Saya bukan orang pertama yang mengalami kesalahan seperti itu. Lihatlah deskripsi "Paket B" di artikel ini sqlmag.com/t-sql/… . Penulis memiliki masalah yang sama.
jyao

10

Melihat masalah Anda dari sudut pandang SSIS, saya merasa alasan mengapa hal ini memakan waktu begitu lama adalah karena Anda tidak melakukan batching. Ini dapat menyebabkan terlalu banyak baris yang mengisi pipa SSIS dan sebagai akibatnya dapat menghambat kinerja SSIS Anda. Yang perlu Anda lakukan adalah mengubah baris Anda per pengaturan batch dan mungkin ukuran komit insert maksimum Anda. Sekarang apa yang Anda atur ini juga akan tergantung pada jumlah memori yang tersedia untuk server SSIS Anda? Berapa kecepatan disk instance SQL Server Anda? Cara terbaik untuk melakukan ini adalah tes. Misalnya, gunakan 10.000. Ini akan mengirim batch ke server 10.000 pada saat yang sama sehingga menjaga pipa Anda dari pengisian berlebih dan akan membantu menjalankan proses ini lebih cepat. Pengaturan ini diatur di tujuan OLEDB Anda.

Tujuan OLEDB

Jika ini merupakan masalah, Anda juga dapat menambahkan menjalankan tugas SQL sebelum dan sesudah untuk melakukan seperti yang disarankan @AaronBertrand dan menghapus / menambahkan kembali setiap indeks atau kendala ke tabel.


1
Ada pertanyaan bagus tentang apa yang dimaksud dengan "pemuatan cepat" di tempat lain di DBA.SE: dba.stackexchange.com/questions/141430/… .
Jon of All Trades
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.