Pengaruh indeks pada pernyataan pembaruan di mana kolom pembaruan tidak ada dalam indeks

16

Saya selalu melihat orang mengatakan bahwa indeks melambat update, deletedan insert. Ini digunakan sebagai pernyataan selimut, seolah-olah itu mutlak.

Sementara menyetel basis data saya untuk meningkatkan kinerja, saya terus menghadapi situasi ini yang tampaknya bertentangan dengan aturan itu secara logis untuk saya, dan di mana pun saya tidak dapat menemukan orang mengatakan atau menjelaskan dengan cara apa pun sebaliknya.

Dalam SQL Server, dan saya percaya / menganggap sebagian besar DBMS lainnya, indeks Anda dibuat berdasarkan kolom spesifik yang Anda tentukan. Sisipan dan penghapusan akan selalu memengaruhi seluruh baris, jadi tidak mungkin mereka tidak akan memengaruhi indeks, tetapi pembaruan tampaknya sedikit lebih unik, mereka hanya dapat memengaruhi kolom tertentu saja secara spesifik.

Jika saya memiliki kolom yang tidak termasuk dalam indeks apa pun dan saya memperbaruinya, apakah itu diperlambat hanya karena saya memiliki indeks pada kolom lain dalam tabel itu?

Sebagai contoh, katakan dalam Usertabel saya, saya memiliki satu atau dua indeks, kunci utama yang merupakan kolom Peningkatan Identitas / Otomatis, dan mungkin yang lain pada beberapa kolom kunci asing.
Jika saya memperbarui kolom tanpa indeks langsung di atasnya, seperti misalnya nomor telepon atau alamat mereka, apakah pembaruan ini melambat karena saya memiliki indeks pada tabel ini di kolom lain di kedua situasi? Kolom yang saya perbarui tidak dalam indeks, jadi secara logis, indeks tidak boleh diperbarui, bukan? Jika ada, saya akan berpikir mereka dipercepat jika saya menggunakan indeks di klausa WHERE.

Ryan
sumber
so there is no way they will not affect the indexkecuali untuk indeks yang difilter ...
usr
Saya pikir indeks non-tertutup, non-clustered sebagai berisi pointer ke catatan (biasanya dalam node daun indeks tabel berkerumun). Saya akan berpikir bahwa satu situasi menyebabkan perlambatan selama UPDATE (atribut tidak termasuk) mungkin situasi di mana UPDATE menyebabkan catatan bergerak dalam indeks cluster. Saya masih tidak yakin apakah gerakan akan menyebabkan pointer berubah, ATAU jika pointer hanyalah nilai KUNCI ke dalam indeks berkerumun, dalam hal ini pembaruan lokasi yang mungkin tidak masalah karena sistem hanya akan melakukan pencarian KUNCI untuk mendapatkan nilai rekaman.
Jmoney38

Jawaban:

6

Anda benar bahwa memperbarui kolom yang tidak diindeks tidak akan menyebabkan perubahan pada indeks. Dalam kasus sederhana, juga tidak akan ada dampak keseluruhan pada tabel.

Jika kueri dapat menggunakan Indeks untuk mencari data, itu dapat mempercepat pencarian, tetapi perilaku yang tepat (tergantung pada merek SQL Anda) mungkin berbeda dari merek SQL lain. (Saya menggunakan Microsoft SQL Server terutama.)

Tentu saja, memperbarui kolom dengan volume data yang jauh lebih besar dapat menyebabkan perpindahan baris ke halaman yang berbeda, dan lain-lain.

RLF
sumber
1
SQL Server disebutkan dalam OP, saya menambahkan tag, jadi saya pikir Anda dapat mengasumsikan SQL Server
Tom V - Team Monica
10

Untuk sistem modern yang relatif cepat, penambahan satu indeks ke tabel OLTP mungkin hampir tidak terdeteksi dari sudut pandang kinerja untuk sebagian besar sistem . Karena itu, Anda seharusnya tidak membuat indeks yang tidak perlu, dan Anda mungkin tidak boleh membuat indeks satu kolom untuk setiap kolom dalam sebuah tabel.

Anda benar dalam asumsi bahwa untuk banyak pertanyaan keberadaan indeks yang berguna akan menghasilkan peningkatan kecepatan yang sangat nyata.

Meskipun pertanyaan Anda tampaknya seputar kinerja, ada beberapa masalah potensial lainnya seputar penambahan indeks, termasuk tetapi tidak terbatas pada:

  1. Waktu yang diperlukan untuk membuat indeks dapat mengakibatkan pemblokiran sementara indeks ditambahkan ke tabel. Kunci ini berumur pendek, dan kemungkinan besar tidak akan membuat masalah besar.

  2. Perubahan indeks mengakibatkan rencana eksekusi tidak valid untuk semua rencana yang merujuk tabel yang mendasarinya. Ketika rencana eksekusi tersebut dikompilasi ulang, kinerja dapat berubah negatif untuk beberapa permintaan.

  3. Modifikasi indeks dapat menghasilkan kueri yang mengembalikan kesalahan di mana tidak ada yang sebelumnya dikembalikan. Ambil kasus indeks yang difilter yang digunakan untuk mengembalikan tanggal yang terkandung dalam bidang varchar; jika filter menghilangkan baris apa pun yang bukan tanggal, dan filter yang kemudian diubah, kueri yang bergantung pada indeks itu sekarang mungkin gagal ketika mencoba untuk mengkonversi data non-tanggal.

  4. Indeks baru dapat menyebabkan urutan eksekusi berubah yang mengakibatkan kemungkinan deadlock terjadi di tempat yang sebelumnya tidak terjadi.

Max Vernon
sumber
"Jalur kode yang diperlukan untuk pembaruan ketika indeks tidak akan terpengaruh masih perlu dievaluasi" ini tidak benar. Fase kompilasi / optimasi akan tahu betul indeks apa yang perlu diperbarui, jika ada, dan akan membuat rencana yang sesuai. Pernyataan UPDATE yang tidak mengubah (menyatakan dalam daftar SET) kolom dalam indeks (termasuk INCLUDE dan kolom kunci berkerumun) tidak akan harus memperbarui indeks itu, dan tahap eksekusi bahkan tidak akan menyentuhnya. HAPUS dan INSERT jelas menyentuh semua kolom (secara logis) dan harus memperbarui semua indeks.
Remus Rusanu
@RemusRusanu tetapi tidakkah perlu dievaluasi jika indeks dapat digunakan untuk menemukan baris yang perlu diperbarui?
Tom V - Tim Monica
@RemusRusanu - Saya kira begitu QO telah menyusun rencana, tidak perlu lagi CPU; Namun untuk menyusun rencana itu tentu perlu melakukan itu. Jika rencana sering dikompilasi, mungkin akan ada sedikit perbedaan.
Max Vernon
@TomV menggunakan indeks untuk mencari baris kandidat hapus / perbarui adalah topik yang sama sekali berbeda. Jika itu masalahnya, keuntungan dari menempatkan baris melalui indeks harus membebani masalah biaya pemeliharaan indeks.
Remus Rusanu
@ MaxVernon Saya berpendapat bahwa tidak ada skenario yang valid dari kompilasi ulang DML (UPDATE). Saya membeli beberapa case untuk kompilasi valid (tidak dapat dihindari?) Untuk query ad-hoc. Tapi DML? Apa jenis aplikasi yang dapat membuat pernyataan UPDATE unik ad-hoc? Kompilasi ulang yang sering dilakukan dengan DML berteriak keras "Parameterisasi saya".
Remus Rusanu
-2

Jika operasi pembaruan menargetkan kolom ukuran tetap yang tidak diindeks (seperti bilangan bulat), biasanya tidak lambat, tetapi dibandingkan dengan pernyataan pilih, pembaruan tersebut akhirnya harus ditulis pada disk lambat juga.

Sorin
sumber