Apakah lebih baik membuat indeks sebelum mengisi tabel dengan data, atau setelah data ada?


92

Saya memiliki tabel sekitar 100 juta baris yang akan saya salin untuk diubah, menambahkan indeks. Saya tidak terlalu peduli dengan waktu yang dibutuhkan untuk membuat tabel baru, tetapi apakah indeks yang dibuat akan lebih efisien jika saya mengubah tabel sebelum memasukkan data atau memasukkan data terlebih dahulu dan kemudian menambahkan indeks?

Jawaban:


117

Membuat indeks setelah penyisipan data adalah cara yang lebih efisien (bahkan sering direkomendasikan untuk menghapus indeks sebelum impor batch dan setelah impor membuatnya kembali).

Contoh sintetik (PostgreSQL 9.1, mesin pengembangan lambat, satu juta baris):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

Sisipkan dan kemudian buat indeks - sekitar 12 detik

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

Buat indeks dan kemudian masukkan - sekitar 25,5 detik (lebih dari dua kali lebih lambat)


5
+1, indeks akan sangat memperlambat operasi yang melibatkan tugas penyisipan baris 100 juta, jadi lebih baik untuk melepaskannya dan membuatnya kembali.
code4life

11

Mungkin lebih baik membuat indeks setelah baris ditambahkan. Tidak hanya akan lebih cepat, tetapi keseimbangan pohon mungkin akan lebih baik.

Edit "penyeimbangan" mungkin bukan pilihan istilah terbaik di sini. Dalam kasus b-tree, definisi itu seimbang. Namun bukan berarti b-tree memiliki layout yang optimal. Distribusi simpul anak dalam orang tua bisa jadi tidak merata (menyebabkan lebih banyak biaya di pembaruan mendatang) dan kedalaman pohon bisa menjadi lebih dalam dari yang diperlukan jika penyeimbangan tidak dilakukan dengan hati-hati selama pembaruan. Jika indeks dibuat setelah baris ditambahkan, kemungkinan besar indeks akan memiliki distribusi yang lebih baik. Selain itu, halaman indeks pada disk mungkin memiliki lebih sedikit fragmentasi setelah indeks dibuat. Sedikit lebih banyak informasi di sini


2

Ini tidak masalah pada masalah ini karena:

  1. Jika Anda menambahkan data terlebih dahulu ke tabel dan setelah itu Anda menambahkan indeks. Waktu pembuatan indeks Anda akan lebih O(n*log(N))lama (di mana nbaris ditambahkan). Karena waktu gerating pohon adalah O(N*log(N))jika Anda membaginya menjadi data lama dan data baru yang Anda dapatkan, O((X+n)*log(N))ini dapat dengan mudah diubah O(X*log(N) + n*log(N))dan dalam format ini Anda dapat melihat apa yang akan Anda tunggu lagi.
  2. Jika Anda menambahkan indeks dan setelah itu memasukkan data. Setiap baris (Anda memiliki nbaris baru) Anda mendapatkan lebih lama memasukkan waktu tambahan yang O(log(N))dibutuhkan untuk meregenerasi struktur pohon setelah menambahkan elemen baru ke dalamnya (kolom indeks dari baris baru, karena indeks sudah ada dan baris baru ditambahkan maka indeks harus dibuat ulang agar seimbang struktur, biaya ini di O(log(P))mana Padalah kekuatan indeks [elemen dalam indeks] ). Anda memiliki nbaris baru kemudian akhirnya Anda memiliki n * O(log(N))maka O(n*log(N))ringkasan waktu tambahan.

1

Indeks yang dibuat setelahnya jauh lebih cepat dalam banyak kasus. Contoh kasus: 20 juta baris dengan teks lengkap di varchar (255) - Indeks (Nama Bisnis) di tempat saat mengimpor baris - kecocokan dengan waktu hingga 20 detik dalam kasus terburuk. Jatuhkan indeks dan buat ulang - cocokkan dengan waktu kurang dari 1 detik setiap kali


-2

Saya tidak yakin itu akan sangat penting demi efisiensi indeks, karena dalam kedua kasus Anda memasukkan data baru ke dalam indeks. Server tidak akan tahu seberapa tidak seimbangnya indeks sampai setelah dibangun, pada dasarnya. Kecepatan bijaksana, tentu saja, lakukan penyisipan tanpa indeks.

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.