Saya memiliki tabel 500 juta baris (dan terus bertambah)
Saya melakukan yang berikut ini untuk meningkatkan kinerja sisipan:
Di sisi basis data:
- menjatuhkan semua indeks dan batasan
- logging dinonaktifkan
Di sisi aplikasi:
- beralih dari entitas yang dikelola JPA ke kueri insert asli, menambahkan LAMPIRAN petunjuk Oracle ke kueri
- mencoba komit dalam batch per 1k / 2k / 3k baris
- mencoba menulis secara paralel (beberapa utas, jumlah utas = ke jumlah inti pada server) ke satu tabel
Ini memberi saya sekitar 300 baris per detik
Selain itu dicoba:
- tulis secara paralel dalam batch ke beberapa tabel (untuk mengelompokkan kemudian mengembalikan hasil menggunakan UNION)
Ini memberi saya sekitar 1rb baris per detik, tetapi di atas meja kosong. Tetapi ketika saya mengisi tabel dengan data dummy (masing-masing 200 juta), kecepatan insert turun menjadi 250 - 300 per detik.
Adakah yang bisa menyarankan apa lagi yang bisa saya lakukan untuk mempercepat insert? Pada dasarnya saya ingin mengerti apa itu (apa yang bisa) bottleneck dulu.
UPD: Tabel dipartisi berdasarkan tanggal penyisipan, tabel memiliki sekitar 60 kolom - sebagian besar kolom adalah VARCHAR2 (2000 BYTE)
/*+APPEND*/
petunjuk tersebut diabaikan pada sisipan baris tunggal (jika Anda tidak perluINSERT INTO ... SELECT
repot menambahkan). (3) Anda harus menyiapkan contoh SQL * Loader dengandirect=true
menetapkan dasar seperti yang disarankan oleh @parsifal.Jawaban:
Baru saja melihat pembaruan, tabel 60-col dengan sebagian besar bidang VARCHAR (2k) - yaitu (berpotensi) tabel monster.
Hal pertama yang pertama ...
Anda harus memahami hambatan Anda PERTAMA. Di sisi aplikasi, kembalilah ke solusi batch-threaded single-threaded Anda (1/2 / 3k sekaligus) dan mulai jalankan dan login ke mesin DB dan jalankan 'top' - lihat berapa banyak waktu proses DB mengambil DAN berapa banyak (jika ada) wa% waktu mesin ditampilkan.
Jika top menunjukkan kapan saja wa%, itu berarti DB Anda terikat I / O dan Anda mungkin perlu mempertimbangkan beberapa mesin DB (pecahan) atau mempertimbangkan melempar SSD pada mesin host.
Itu dia; penelitian Anda berhenti di sini. Tidak masalah berapa banyak CPU yang diambil oleh DB atau seberapa jenuh klien aplikasi Anda; jika Anda menekan masalah latensi I / O pada host DB, itu secepat itu akan PERNAH pergi untuk Anda.
TIP Jika perubahan perangkat keras keluar dari pertanyaan, tergantung pada sistem file yang Anda jalankan (Linux) Anda dapat mencoba menonaktifkan logging atau penulisan metadata untuk DB untuk sedikit meningkatkan kinerja pada tingkat sistem file. Anda dapat melakukan hal serupa pada NTFS, tetapi ini hanya akan memberi Anda sedikit dorongan. Ini tidak akan 2x.
Sekarang, yang kedua ...
Katakanlah Anda memiliki waktu tunggu sebentar lagi tetapi CPU Anda dipatok sepenuhnya oleh proses DB. Satu-satunya pilihan Anda sekarang adalah untuk memperkenalkan lebih banyak mesin DB (pecahan) dan membagi pekerjaan.
Sekali lagi, Anda sudah selesai dengan penelitian Anda jika ini masalahnya. Tidak ada yang dapat Anda lakukan untuk mengubah CPU agar lebih cepat.
Terakhir, hal ketiga ... ketiga ...
Katakanlah DB tidak melakukan banyak hal. Lalu, buka mesin klien yang menjalankan batch insert dan periksa beban CPU - apakah dipatok? Jika demikian, jalankan beberapa mesin lagi melakukan insert batch yang sama persis dan lihat apakah Anda bisa mendapatkan jalan linier.
Jika CPU tidak dipatok, jalankan beberapa utas lagi di mesin yang sama hingga dipatok dan lihat bagaimana skala DB.
Saya pikir Anda mungkin sudah mencobanya, jadi tebakan saya adalah bahwa host klien Anda sudah dipatok (dan lebih banyak utas tidak akan membuat perbedaan) atau DB sudah mencapai batasnya dan tidak dapat skala lebih jauh.
Tambahan
Melakukan penyisipan mentah pada tabel yang tidak diindeks yang tidak memiliki sampah di dalamnya pada dasarnya adalah operasi APPEND yang harus berjalan secepat disk dapat menangani penulisan.
Membuat lebih banyak tabel pada mesin host yang sama tidak akan membantu, jika apa pun itu akan meningkatkan upaya disk Anda (untuk sampai ke tabel lain pada disk untuk ditambahkan) dan akan memperlambat segalanya.
Sangat penting untuk mencari tahu kemacetan itu terlebih dahulu, lalu kita bisa mengoptimalkannya.
Semoga itu bisa membantu! Buat kami tetap diposting.
sumber
Menjalankan penyisipan jalur langsung dengan petunjuk tambahan menyebabkan kunci eksklusif akan diambil terhadap seluruh tabel, sehingga memiliki beberapa utas yang melakukan penyisipan tidak akan membantu. Anda perlu secara eksplisit mengatasi partisi yang berbeda dengan setiap sisipan ...
... untuk mendapatkan kunci eksklusif tingkat partisi. Anda tidak akan dapat melakukannya dengan tabel dipartisi pada tanggal penyisipan, kemungkinan besar, tetapi Anda bisa menggunakan partisi gabungan (bukan sub-partisi) untuk mendapatkan beberapa partisi per rentang unik tanggal memasukkan.
Jangan komit di tengah-tengah sisipan, hanya di akhir.
sumber