Bulk Insert Data Besar di SQL dengan Efisien
Blog/Tutorial SQL/Bulk Insert Data Besar di SQL dengan Efisien

Bulk Insert Data Besar di SQL dengan Efisien

BimaBima
·28 Oktober 2026·11 menit baca

Penulis

Bima

Bima

Founder & Data Professional

Bagikan

TL;DR

Bulk insert adalah memasukkan banyak baris ke database dalam satu operasi, bukan satu perintah per baris. Cara paling cepat: pakai multi-row INSERT dengan banyak baris di satu VALUES, atau perintah COPY buat impor dari file. Bungkus dalam satu transaksi biar nggak commit tiap baris. Untuk jutaan baris, COPY di PostgreSQL biasanya jauh mengungguli INSERT biasa.

Bulk insert adalah memasukkan banyak baris ke database dalam satu operasi, bukan satu perintah INSERT per baris. Buat data besar, ini beda antara proses 2 detik dan proses 5 menit.

Insert satu per satu itu lambat karena tiap perintah punya overhead: parsing, roundtrip ke server, dan commit. Kali sejuta baris, overhead-nya numpuk.

Aku bahas tiga cara bulk insert dari yang paling gampang sampai paling cepat, kapan pakai masing-masing, plus tips index dan transaksi yang sering kelupaan.

Kenapa insert satu per satu lambat?

Insert satu baris per perintah lambat karena tiap perintah menanggung overhead penuh: parsing SQL, roundtrip jaringan ke server, dan commit transaksi terpisah. Buat ribuan baris, overhead berulang ini jauh lebih mahal dari waktu nulis datanya sendiri.

Bayangin kamu insert 100.000 baris, masing-masing perintah sendiri. Itu 100.000 roundtrip bolak-balik ke server.

Tiap roundtrip makan waktu jaringan, walau cuma milidetik. Dan tiap commit maksa database nulis ke disk. Numpuk semua, prosesnya bisa bermenit-menit.

Cara 1: Multi-row INSERT

Multi-row INSERT masukin banyak baris dalam satu perintah dengan menuliskan beberapa set nilai di klausa VALUES, dipisah koma. Ini cara paling sederhana buat mempercepat, dan didukung hampir semua database. Satu perintah, satu roundtrip, banyak baris sekaligus.

INSERT INTO transaksi (tanggal, produk, jumlah)
VALUES
  ('2026-10-28', 'Beras 5kg', 12),
  ('2026-10-28', 'Minyak 1L', 8),
  ('2026-10-28', 'Gula 1kg', 15),
  ('2026-10-28', 'Telur 1kg', 20);

Empat baris masuk dalam satu perintah. Bandingin sama empat perintah INSERT terpisah: overhead-nya seperempatnya.

Batasannya, jangan terlalu banyak baris dalam satu perintah. Kebanyakan database punya batas ukuran query. Aman biasanya 500 sampai 1.000 baris per batch. Kalau datanya jutaan, pecah jadi beberapa batch.

Cara 2: Bungkus dalam satu transaksi

Kalau kamu tetap harus insert baris per baris (misalnya dari loop aplikasi), bungkus semuanya dalam satu transaksi. Ini mencegah database commit tiap baris, yang jadi sumber lambat terbesar.

BEGIN;

INSERT INTO transaksi (tanggal, produk, jumlah) VALUES ('2026-10-28', 'Beras 5kg', 12);
INSERT INTO transaksi (tanggal, produk, jumlah) VALUES ('2026-10-28', 'Minyak 1L', 8);
-- ... ribuan insert lain

COMMIT;

Tanpa transaksi eksplisit, tiap INSERT auto-commit dan nulis ke disk sendiri-sendiri. Dengan satu transaksi, database nulis sekali di akhir. Dari yang aku ukur di kasus sejenis, membungkus 50.000 insert dalam satu transaksi motong waktu dari sekitar 40 detik jadi di bawah 5 detik.

Gabungin cara ini sama multi-row INSERT buat hasil terbaik: batch multi-row di dalam satu transaksi.

Cara 3: Perintah COPY (paling cepat)

COPY di PostgreSQL adalah cara tercepat memuat data besar, karena dirancang khusus buat impor massal dari file atau stream. Dia melewati banyak overhead pemrosesan per baris yang ada di INSERT. Buat jutaan baris dari file CSV, COPY biasanya jauh mengungguli semua metode INSERT.

COPY transaksi (tanggal, produk, jumlah)
FROM '/path/data_transaksi.csv'
WITH (FORMAT csv, HEADER true);

Kalau file ada di sisi klien, bukan server, pakai \copy di psql:

\copy transaksi (tanggal, produk, jumlah) FROM 'data_transaksi.csv' WITH (FORMAT csv, HEADER true)

Database lain punya padanannya: MySQL pakai LOAD DATA INFILE, SQL Server pakai BULK INSERT atau utilitas bcp. Prinsipnya sama, satu perintah muat massal dari file.

Perbandingan tiga cara

CaraKecepatanKapan dipakai
Insert satu per satuPaling lambatData kecil, beberapa baris saja
Multi-row INSERTCepatRatusan sampai ribuan baris dari kode
Transaksi + multi-rowLebih cepatPuluhan ribu baris dari aplikasi
COPY / LOAD DATAPaling cepatImpor jutaan baris dari file

Contoh Kasus: Impor Data Transaksi Toko Berkah

Toko Berkah pindah dari catatan spreadsheet ke database PostgreSQL. Ada 1,2 juta baris transaksi historis dalam file CSV yang harus dimuat sekali jalan.

Percobaan pertama pakai loop aplikasi, insert baris per baris tanpa transaksi. Prosesnya jalan lebih dari 20 menit dan belum kelar. Kelamaan.

Solusinya ganti ke COPY. Struktur tabelnya: transaksi (id SERIAL, tanggal DATE, outlet TEXT, produk TEXT, jumlah INT, total BIGINT).

-- Nonaktifkan index dulu buat impor lebih cepat (opsional)
DROP INDEX IF EXISTS idx_transaksi_tanggal;

-- Muat semua data dari file CSV
\copy transaksi (tanggal, outlet, produk, jumlah, total) FROM 'transaksi_2026.csv' WITH (FORMAT csv, HEADER true)

-- Bikin ulang index setelah impor selesai
CREATE INDEX idx_transaksi_tanggal ON transaksi (tanggal);

Dengan COPY, 1,2 juta baris masuk dalam sekitar 8 detik. Turun dari lebih 20 menit jadi hitungan detik, sekitar 150 kali lebih cepat dari pola loop awal.

Kalau data impormu mungkin ada duplikat kunci, gabung sama teknik INSERT ON CONFLICT biar baris bentrok ditangani tanpa error. Dan setelah impor, cek composite index di SQL biar query laporan tetap ngebut.

Tips: matikan index saat impor besar

Index bikin insert lebih lambat, karena tiap baris baru harus ikut memperbarui index. Buat impor sekali jalan yang besar, sering lebih cepat drop index dulu, muat data, lalu bikin ulang index.

Alurnya:

  1. Drop index yang nggak perlu selama impor.
  2. Jalankan bulk insert atau COPY.
  3. Bikin ulang index setelah data masuk.

Bikin index sekali di akhir atas seluruh data lebih efisien dari memperbarui index jutaan kali selama impor. Tapi ini cuma layak buat impor besar yang jarang. Buat insert rutin harian, biarkan index tetap ada.

Kesalahan Umum saat Bulk Insert

  • Insert per baris tanpa transaksi. Ini penyebab paling umum proses lambat. Bungkus dalam satu transaksi atau pakai multi-row.
  • Batch kegedean. Satu perintah dengan jutaan baris bisa nabrak batas ukuran query atau makan memori. Pecah jadi batch 500 sampai 1.000 baris.
  • Lupa bikin ulang index. Kalau drop index buat impor, jangan lupa bikin lagi. Kalau nggak, query jadi lambat.
  • COPY dengan format salah. Kolom di CSV harus cocok urutan dan tipenya sama definisi tabel. Header nggak dicentang bikin baris judul ikut masuk sebagai data.
  • Impor besar di jam sibuk. Bulk insert berat bikin database sibuk. Jalankan di jam sepi kalau bisa.

FAQ

Apa cara tercepat bulk insert di PostgreSQL?

Perintah COPY adalah yang tercepat buat data besar, karena dirancang khusus buat impor massal dan melewati banyak overhead per baris yang ada di INSERT. Buat memuat jutaan baris dari file CSV, COPY bisa berkali-kali lipat lebih cepat dari INSERT biasa. Kalau file ada di sisi klien, pakai perintah \copy di psql. Buat data dari kode aplikasi, multi-row INSERT dalam satu transaksi jadi pilihan terbaik berikutnya.

Berapa baris ideal per batch multi-row INSERT?

Biasanya 500 sampai 1.000 baris per perintah jadi titik seimbang yang bagus. Terlalu sedikit, kamu nggak dapat banyak keuntungan dari batching. Terlalu banyak, kamu bisa nabrak batas ukuran query atau makan memori. Buat data jutaan baris, pecah jadi banyak batch berukuran ini dan jalankan berurutan dalam satu transaksi. Angka pastinya bisa kamu sesuaikan lewat uji coba di lingkunganmu.

Apakah perlu mematikan index saat bulk insert?

Cuma buat impor besar yang sekali jalan. Kalau kamu muat jutaan baris ke tabel baru, drop index dulu, muat data, lalu bikin ulang index sering lebih cepat, karena database nggak perlu memperbarui index tiap baris. Tapi buat insert rutin harian dalam jumlah sedang, biarkan index tetap ada. Drop dan bikin ulang index nggak sepadan buat batch kecil.

Kenapa membungkus insert dalam transaksi mempercepat?

Karena tanpa transaksi eksplisit, tiap INSERT auto-commit dan memaksa database menulis ke disk sendiri-sendiri. Menulis ke disk itu operasi mahal. Dengan membungkus banyak insert dalam satu transaksi, database cukup menulis sekali saat COMMIT di akhir. Ini bisa memangkas waktu secara drastis, kadang dari puluhan detik jadi beberapa detik buat puluhan ribu baris.

Bisakah bulk insert dipakai kalau ada kemungkinan duplikat?

Bisa, tapi kamu perlu menangani konfliknya. Di PostgreSQL, gabungkan bulk insert dengan ON CONFLICT buat memutuskan apakah baris bentrok diabaikan atau diperbarui. Kalau pakai COPY, dia nggak mendukung penanganan konflik langsung, jadi triknya muat dulu ke tabel sementara, lalu pindahkan ke tabel utama pakai INSERT ON CONFLICT. Cara ini menjaga impor tetap cepat sekaligus aman dari error duplikat.

Penutup

Bulk insert soal mengurangi overhead berulang. Ringkasnya:

  • Multi-row INSERT buat ribuan baris dari kode, bungkus dalam satu transaksi.
  • COPY atau LOAD DATA buat impor jutaan baris dari file, ini tercepat.
  • Buat impor besar sekali jalan, drop index dulu lalu bikin ulang setelah selesai.

Mau lancar nulis query yang efisien buat data besar? Latihan langsung di NgulikSQL, dan lanjut baca INSERT ON CONFLICT di PostgreSQL buat nangani duplikat saat impor.

Referensi resmi: dokumentasi COPY PostgreSQL.

Coba Langsung

Mau praktek langsung? Mulai latihan SQL gratis

Latihan interaktif, langsung di browser.

Buka NgulikSQL →
Bagikan:
Bima
Ditulis oleh

Bima

Founder & Data Professional

Founder Ngulik Data. Passionate about making data analysis accessible for everyone.

Artikel terkait

Fungsi NTH_VALUE di SQL untuk Ambil Nilai ke-N (2026)
Tutorial SQL
29 Desember 2026•9 menit baca

Fungsi NTH_VALUE di SQL untuk Ambil Nilai ke-N (2026)

NTH_VALUE ngambil nilai baris ke-N dalam window, tapi frame default-nya sering bikin hasil NULL. Ini sintaksnya, cara benerin frame, plus contoh transaksi toko.

BimaBima
Running Max dan Min dengan Window Function SQL
Tutorial SQL
26 Desember 2026•11 menit baca

Running Max dan Min dengan Window Function SQL

Lacak nilai tertinggi dan terendah berjalan di SQL pakai window function MAX dan MIN OVER. Ini sintaks, frame clause, dan contoh rekor omzet toko.

BimaBima
Analisa Afinitas Produk (Cross-Sell) dengan SQL
Tutorial SQL
23 Desember 2026•12 menit baca

Analisa Afinitas Produk (Cross-Sell) dengan SQL

Produk apa yang sering dibeli bareng? Analisa afinitas produk pakai SQL self JOIN jawab itu. Ini cara hitung support, confidence, dan lift buat strategi cross-sell.

BimaBima
Kembali ke Blog
Ngulik Data logoNgulik Data

Platform edukasi data lengkap untuk professionals Indonesia. Belajar SQL, Data Analysis, dan lebih banyak lagi dengan praktek langsung dan feedback real-time.

© 2026 Ngulik Data. Semua hak dilindungi.

TAUTAN
BantuanHargaDatasetBlogAfiliasi
LEGAL
Syarat & KetentuanKebijakan Privasi
Ngulik Data
DatasetLeaderboardBlogStore