Apakah ini optimasi prematur untuk menambahkan indeks basis data?

61

Seorang kolega saya hari ini menyarankan agar kami memeriksa semua pertanyaan dalam aplikasi kami dan menambahkan indeks yang sesuai.

Saya merasa ini adalah optimasi prematur karena aplikasi kami bahkan belum dirilis. Saya menyarankan untuk memantau permintaan lambat setelah kami tayang dan kemudian menambahkan indeks yang sesuai.

Apa konsensus umum ketika merancang basis data Anda, haruskah Anda menambahkan indeks yang cocok setiap kali Anda menulis kueri baru? Atau lebih baik memantau saja dan melihat bagaimana hasilnya?

Marco de Jongh
sumber
32
Ini mungkin masalah pendapat, namun saya merasa bahwa beberapa indeks dapat ditambahkan secara apriori.
Basile Starynkevitch
2
@ BasileStarynkevitch Sepenuhnya setuju bahwa kami telah memiliki indeks kunci utama dan karya-karya. Tapi di mana Anda menarik garis?
Marco de Jongh
1
Dua sen dari pengalaman saya: Saya sedang menguji beberapa permintaan pencarian awal saya pada subset dari database kami. Tes yang saya jalankan benar-benar baik pada salinan lokal saya. Saya kemudian mendorong aplikasi ke area pementasan yang meng-host database lengkap. Tes saya berjalan dalam <500 ms , sedangkan sistem pementasan butuh beberapa menit untuk menyelesaikan. Bos saya benar-benar bingung mengapa aplikasi tidak memuat. Jelaskan operasi -type adalah teman Anda ... Setidaknya cari pindaian berurutan pada tabel besar, paling tidak!
Chris Cirefice
2
Tidak menambahkan indeks seperti menggunakan bubblesort. Paling sering Anda tidak akan menemukan masalah ketika Anda mengujinya, tetapi begitu program Anda mulai ditingkatkan secara langsung Anda berada dalam untuk banyak masalah. Dan indeks dapat dengan mudah membuat faktor 100 perbedaan kecepatan.
Pieter B
3
Selalu ingat: Indeks bukanlah hal ajaib yang akan mempercepat kueri Anda. Indeks akan dikenakan biaya pada sebagian besar Operasi DML dan tergantung pada jenisnya dapat menyebabkan banyak menunggu ketika banyak orang memperbarui tabel yang sama. Untuk kueri: Ada banyak kueri yang tidak mendapat manfaat sama sekali dari indeks, di mana FTS adalah yang tercepat atau di mana Pemisahan melakukan semua pekerjaan untuk Anda. - Hanya tambahkan indeks di mana Anda TAHU mereka akan bermanfaat!
Falco

Jawaban:

132

Optimalisasi prematur adalah "mengoptimalkan" sesuatu karena perasaan intuitif yang samar-samar yang, Anda tahu, ini mungkin akan lambat, terutama yang merusak pembacaan kode dan pemeliharaan . Itu tidak berarti dengan sengaja tidak mengikuti praktik-praktik baik yang sudah mapan mengenai kinerja.

Kadang-kadang itu adalah garis yang sulit untuk digambarkan, tetapi saya pasti akan mengatakan bahwa tidak menambahkan indeks sebelum Anda ditayangkan adalah optimasi yang terlalu terlambat ; ini akan menghukum pengadopsi awal - pengguna Anda yang paling bersemangat dan paling penting - dan memberi mereka pandangan negatif tentang produk Anda, yang kemudian akan mereka sebarkan dalam ulasan, diskusi, dll. Memantau pertanyaan untuk menemukan titik nyeri yang perlu diindeks adalah ide yang bagus, tapi saya akan memastikan untuk melakukannya selambat-lambatnya beta.

Mason Wheeler
sumber
11
Ya, itu harus dilakukan dalam fase pengujian beban
Alvaro
152
Mengoptimalkan sebelum Anda tahu di mana bagian yang lambat adalah optimasi prematur. Melepaskan benda itu sebelum Anda tahu di mana bagian yang lambat adalah pelepasan prematur !
MathematicalOrchid
4
@MathematicalOrchid: Itu ungkapan yang bagus! Bolehkah saya meminjamnya di tempat lain?
Pieter Geerkens
3
@PieterGeerkens Tentu, jatuhkan dirimu! ;-) Saya hanya sedih bahwa 91+ upvotes tidak memberi saya rep ... heh.
MathematicalOrchid
3
@MathematicalOrchid seharusnya menjadi jawaban. Bisa mencalonkan diri untuk jawaban "terkecil-langsung-ke-titik".
Mindwin
48

memonitor permintaan lambat setelah kami tayang

karena tidak ada yang mengatakan kualitas seperti membuat pengguna Anda menderita karena kurangnya desain!

Anda harus tahu kueri mana yang perlu indeks ketika Anda mendesain tabel, Anda tahu kolom mana yang dipertanyakan di mana klausa dan bergabung. Ini harus sudah diindeks karena apa yang mungkin tidak terlihat dalam lingkungan hidup dapat dengan cepat menjadi jelas ketika beban atau data yang disimpan meningkat. Apa yang tidak ingin Anda lakukan ketika ini terjadi adalah menampar indeks pada setiap permintaan 'lambat', Anda akan berakhir dengan indeks pada segalanya.

gbjbaanb
sumber
10
Baik. Pertimbangkan indeks sebagai bagian dari desain basis data. Gunakan indeks untuk menghindari pemindaian tabel penuh untuk kueri apa pun yang biasanya dilakukan pengguna akhir secara real-time.
AE
1
@DocBrown Saya tidak begitu yakin, ketika Anda mendesain meja Anda harus (atau harus memiliki) beberapa pemahaman bagaimana itu akan digunakan. Tabel orang akan ditanyai dengan ID, atau mungkin nama keluarga. Jika seseorang mulai mengakses melalui DoB, alamat atau nomor telepon maka Anda akan menambahkan indeks untuk setiap bidang - dan di mana itu berakhir ?!
gbjbaanb
4
@ gbjbaanb: berakhir ketika orang berhenti menambahkan fitur ke produk, yang mungkin "tidak pernah" tergantung pada metodologi Anda.
Steve Jessop
1
@SteveJessop Maksud saya Anda indeks sesuai dengan kolom utama yang ingin Anda akses. Untuk tabel orang, Anda mungkin memiliki fungsi pencarian (jika Anda lupa nama pengguna Anda, Anda mungkin mencari di email misalnya) tetapi setelah itu Anda selalu menggunakan ID. Jadi ID adalah satu-satunya yang perlu diindeks. Jika Anda melakukan banyak pencarian di bidang lain Anda mungkin ingin indeks, ini akan keluar pada waktunya, tetapi umumnya Anda tidak ingin mengindeks setiap kolom hanya karena seseorang kadang-kadang memutuskan untuk menulis permintaan non-standar, tetapi Anda mungkin menggunakan mekanisme berbeda untuk kasus "satu kali" ini.
gbjbaanb
2
@ gbjbaanb: tentu saja, orang tidak boleh berulang kali mencari nama keluarga yang sama di sebuah meja karena itu merupakan pegangan yang sedikit lebih nyaman bagi mereka untuk menahan daripada kunci yang tepat untuk tabel. Saya akan mengatakan itu adalah kasus apakah tabel diindeks pada nama keluarga atau tidak, pada kenyataannya, karena ada sesuatu yang sangat mencurigakan tentang serangkaian kode yang menganggap itu semua beroperasi pada "pengguna yang sama" tetapi tidak bisa mengelola untuk mengekspresikan ini dalam kode dengan mengingat ID :-) Saya membayangkan kasus di mana kebutuhan untuk reverse-lookup tidak diantisipasi sampai klien menyebutkannya ...
Steve Jessop
26

"Optimalisasi prematur", dalam arti yang merendahkan, berarti optimasi mahal yang mungkin tidak diperlukan. Itu tidak berarti semua optimisasi diterapkan sebelum titik terbaru untuk mencegah kebangkrutan!

Khususnya, itu sah untuk mengoptimalkan berdasarkan tes kinerja sebelum ditayangkan, untuk memastikan Anda dapat memenuhi beberapa persyaratan yang masuk akal (meskipun perkiraan) untuk aplikasi Anda untuk tidak sepenuhnya menyedot.

Minimal Anda harus memuat basis data Anda dengan jumlah data pengujian yang masuk akal dan memeriksa daya tanggap aplikasi Anda. Ini bukan prematur, karena Anda tahu itu akan terjadi, dan itu akan menangkap setiap pertanyaan yang memicu pemindaian yang sangat lambat. Seperti yang dikatakan AE dalam komentar:

Gunakan indeks untuk menghindari pemindaian tabel penuh untuk kueri apa pun yang biasanya dilakukan pengguna akhir secara real-time

Paling tidak, untuk tabel yang direncanakan tumbuh digunakan.

Kemudian sebagai jalan pintas untuk itu, jika Anda memiliki pengalaman yang signifikan dengan mesin database dan Anda sudah merencanakan tes ketika Anda menulis potongan pertama dari kode, maka seringkali Anda akan tahu bahkan tanpa menjalankannya bahwa permintaan Anda menulis akan terlalu lambat tanpa indeks. Tentu saja Anda bebas untuk berpura-pura tidak tahu, dan menonton tes gagal sebelum menambahkan indeks untuk membuatnya lulus, tetapi tidak ada alasan untuk kode yang salah diketahui (karena tidak responsif) untuk ditayangkan.

Steve Jessop
sumber
20

Saya merasa ini adalah optimasi prematur karena aplikasi kami bahkan belum dirilis. Saya menyarankan untuk memantau permintaan lambat setelah kami tayang dan kemudian menambahkan indeks yang sesuai.

Anda tidak dapat memperlakukan pengguna akhir dan lingkungan produksi seperti jaminan kualitas. Dengan kata lain, Anda mengatakan bahwa Anda akan mengetahuinya dalam produksi. Saya pikir itu bukan cara yang benar, dan saya melihat pendekatan itu sangat salah setiap hari .

Anda perlu mengingat satu hal, karena Anda tidak bisa mengecatnya dengan sikat lebar.

Apa beban kerja umum Anda ?

Itu mungkin terdengar jelas atau membosankan, tetapi penting dalam praktiknya. Jika Anda memiliki 10 pertanyaan yang merupakan 98% dari beban kerja Anda (cukup umum, percaya atau tidak), rekomendasi saya akan menjadi analisis yang sulit sebelum produksi . Dengan data yang realistis dan representatif, pastikan 10 pertanyaan itu sebaik mungkin ( sempurna membuang-buang waktu yang berharga, dan hampir tidak dapat dicapai).

Untuk 200 kueri lainnya yang merupakan 2% dari beban kerja , itu adalah pertanyaan yang kemungkinan besar tidak sepadan dengan usaha, dan akan menjadi penyebab keganjilan pemecahan masalah per kasus dalam produksi. Itu juga kenyataan, dan bukan hal yang sangat buruk. Tapi itu tidak berarti mengabaikan praktik terbaik pengindeksan atau membuat asumsi estimasi tentang pengambilan data.

Merupakan praktik yang umum dan baik untuk mengetahui kinerja basis data sebelum produksi. Bahkan, ada posisi yang relatif umum untuk hal semacam ini yang disebut pengembangan DBA .

Tapi...

Beberapa mengambil terlalu jauh dan menjadi gila menambahkan indeks "berjaga-jaga". Seseorang merekomendasikan ini adalah indeks yang hilang? Tambahkan, dan empat variasi lainnya. Itu juga ide yang buruk. Anda tidak hanya perlu memikirkan tentang pengambilan data Anda, tetapi bagaimana dengan modifikasi data? Semakin banyak indeks yang Anda miliki di atas meja, secara umum semakin banyak overhead yang Anda miliki saat Anda memodifikasi data.

Seperti kebanyakan hal, ada keseimbangan yang sehat.

Sebagai catatan kecil yang menyenangkan ... pluralisasi "Indeks"

"Indeks" adalah untuk orang finansial

"Indeks" adalah untuk kita

Thomas Stringer
sumber
2
Ini membutuhkan lebih banyak suara. Saya sangat setuju.
RubberDuck
+1 untuk bit "berjaga-jaga" (itu akan menjadi optimasi prematur). Jika aku bisa, aku memilih lagi untuk bit "beban kerja umum".
David
Mudah-mudahan Anda tahu sebelumnya 10 pertanyaan mana yang termasuk 98%, dan mana yang tidak.
Paŭlo Ebermann
@ PaŭloEbermann Sebagian besar DBMS memiliki kemampuan untuk menangkap informasi itu dengan cepat dan mudah. Dalam hal ini, tidak ada alasan untuk tidak mengetahui.
Thomas Stringer
@ThomasStringer Tentu saja, ini hanya berfungsi jika test case Anda sebelum pergi ke produksi entah bagaimana terkait dengan apa yang dilakukan oleh pengguna nyata dalam produksi.
Paŭlo Ebermann
4

Tidak, ini bukan optimasi prematur, tetapi harus dilakukan dengan benar sebagaimana optimasi seharusnya.

Inilah yang akan saya lakukan:

  1. Muat basis data dengan data uji yang cukup untuk meniru beban produksi. Anda tidak bisa mendapatkan ini 100% akurat tetapi tidak apa-apa: cukup masukkan data saja. Apakah satu tabel memiliki jumlah data yang tetap? Memuatnya. Apakah Anda memiliki satu tabel yang menyimpan banyak data, misalnya tabel apa saja yang menyimpan pertanyaan di situs ini? Muat beberapa juta catatan meskipun hanya data tiruan.
  2. Aktifkan profil di server database Anda.
  3. Bang di aplikasi menggunakan kombinasi skrip otomatis (memberikan volume) dan pengguna nyata (mereka tahu cara memecahkan masalah).
  4. Tinjau data profil. Apakah permintaan spesifik lambat? Periksa menjelaskan rencana dan lihat apakah server database memberitahu Anda ia menginginkan indeks tetapi tidak ada.

Server database adalah perangkat lunak yang kompleks dan cerdas. Mereka dapat memberi tahu Anda cara mengoptimalkannya jika Anda tahu cara mendengarkan.

Kuncinya adalah untuk mengukur kinerja sebelum dan sesudah mengoptimalkan dan dan biarkan database memberi tahu Anda apa yang dibutuhkan .


sumber
3

Mengikuti pola yang terbukti untuk masalah yang diketahui (seperti menemukan catatan dengan ID-nya) bukanlah sesuatu yang prematur. Masuk akal.

Yang mengatakan, indeks tidak selalu bisnis yang mudah. Sering kali sulit untuk mengetahui selama fase desain yang akan bergantung pada indeks lalu lintas Anda dan yang akan menghambat operasi penulisan. Jadi, saya berpendapat untuk memanfaatkan beberapa praktik terbaik desain skema "jelas" (gunakan PK yang sesuai untuk pola baca / tulis yang dirancang dan indeks FK); tetapi, jangan meletakkan indeks pada hal lain sampai stress testing Anda menuntutnya.

svidgen
sumber
Menghabiskan 30 detik ekstra untuk melakukan sesuatu yang hampir pasti untuk meningkatkan kinerja dan sangat tidak membahayakan itu bukanlah "optimasi prematur". Jika 90% operasi di atas meja menggunakan kolom tertentu sebagai kunci, maka pengindeksan itu akan meningkatkan kinerja, atau kinerja tidak akan pernah cukup lambat untuk masalah, dan menambahkan kode untuk membuat indeks mungkin membutuhkan waktu lebih sedikit daripada menentukan apakah itu sangat perlu.
supercat
@supercat "tidak pernah" ... Sampai Anda mulai melihat kebuntuan di lingkungan produksi Anda ...
svidgen
Apa jenis skenario realistis yang Anda bayangkan yang konsisten dengan 90% operasi menggunakan kolom sebagai kunci, dan di mana menambahkan indeks akan menyebabkan kebuntuan?
supercat
@ supercat Saya tidak yakin saya sepenuhnya memahami pencarian Anda. Dalam hal aplikasi aktif, hampir semua peningkatan waktu eksekusi atau jumlah ios berpotensi menyebabkan kebuntuan. ... Tapi, lebih tepatnya, ada atau tidaknya indeks di sebagian besar aplikasi diabaikan sampai database mencapai ukuran kritis dan / atau tingkat konkurensi. Misalnya, ketika semua indeks Anda tidak lagi sesuai dengan memori ...
svidgen
1
Intinya adalah, sulit untuk mengetahui apa susunan kueri Anda sampai kasus penggunaan umum dijalankan melalui tes stres (atau sampai Anda melihat masalah dengan perilaku pengguna yang tidak terduga dalam produksi). Jika Anda memiliki halaman yang kunci dari tablex.fieldy, tapi itu hanya tekan sekali untuk setiap seribu sisipan ... Indeks dapat menghasilkan degradasi bersih.
svidgen
2

Ketika aplikasi Anda dirilis, sudah terlambat.

Tetapi setiap proses pengembangan yang tepat harus mencakup pengujian kinerja.

Gunakan hasil tes kinerja Anda untuk memutuskan indeks mana yang akan ditambahkan, dan verifikasi keefektifannya dengan mengulangi tes kinerja.

Philipp
sumber
Ketika sebuah aplikasi dirilis, ini adalah saat yang tepat untuk mengubah indeks. Lihatlah situs ini, stachexchange, Anda bisa bertaruh topi Anda indeks telah berubah lama setelah ditayangkan.
LosManos
@LosManos: Tidak ada yang membayar untuk menggunakan Stack Exchange.
Lightness Races dengan Monica
@LightnessRacesinOrbit: O contraire, pengiklan membayar untuk menggunakan Stack Exchange.
@JonofAllTrades: Mereka tidak peduli jika kami memiliki beberapa jam kinerja yang buruk karena indeks yang hilang. Maksud saya adalah bahwa sebuah situs web besar yang berorientasi komunitas bebas untuk digunakan dengan siklus distribusi abadi sangat berbeda dari produk komersial mandiri yang dirilis secara berkala. Jadi, SE bukan contoh yang baik.
Lightness Races dengan Monica
1

Meskipun saya tidak berpikir setiap query harus dioptimalkan, indeks adalah bagian dari RDBMS sehingga mereka perlu dipertimbangkan sebelum dirilis. Saat Anda menjalankan kueri, tidak seperti bentuk pemrograman lainnya, Anda tidak memberi tahu sistem cara menjalankannya. Mereka mengembangkan rencana mereka sendiri dan hampir selalu mendasarkannya pada ketersediaan indeks. Susunan dan volume data akan dipertimbangkan juga di waktu mendatang.

Berikut adalah beberapa hal yang akan saya pertimbangkan:

  1. Ada beberapa pertanyaan yang harus Anda identifikasi dalam pengembangan awal Anda yang Anda tahu akan sering digunakan. Fokus pada mereka.
  2. Akan ada permintaan lambat. Dengan mengindeksnya terlebih dahulu, Anda kemudian dapat menentukan apakah kinerjanya masih belum cukup cepat dan kemudian mempertimbangkan desain ulang (Denormalisasi mungkin prematur). Saya lebih suka melakukan ini sebelum rilis. Tidak ada yang menginginkan sistem di mana dibutuhkan 10 menit untuk menemukan sesuatu dalam inventaris.
  3. Indeks dapat meningkatkan kinerja kueri tetapi tidak menghalangi modifikasi data.
  4. Banyak sistem memiliki alat untuk menganalisis permintaan Anda, jadi jangan takut untuk menggunakannya.

Setelah ulasan awal Anda, Anda harus menindaklanjutinya dengan beberapa pertimbangan kapan Anda harus meninjau ini lagi dan bagaimana Anda akan dapat mengumpulkan informasi untuk melakukan ini (memantau penggunaan, mendapatkan salinan data klien, dll.).

Saya menyadari Anda tidak ingin mengoptimalkan secara prematur, tetapi hampir pasti Anda akan memiliki kinerja yang buruk tanpa mengindeks database Anda. Dengan menyingkirkan hal ini, Anda dapat menentukan apakah ada area lain yang menyebabkan masalah kinerja.

JeffO
sumber
0

Itu juga tergantung pada berapa banyak pengguna yang Anda harapkan. Anda pasti harus melakukan beberapa pengujian beban dan memastikan database Anda dapat menjaga 10s hingga 100s hingga 1000s permintaan simultan. Sekali lagi, itu tergantung pada seberapa banyak lalu lintas yang Anda harapkan, dan area apa yang Anda harapkan lebih banyak digunakan daripada yang lain.

Secara umum, saya akan menyelaraskan area yang saya harapkan paling banyak dikunjungi pengguna. Maka saya akan menyesuaikan apa pun yang lambat dari sudut pandang pengalaman pengguna. Setiap kali pengguna harus menunggu sesuatu, mereka mendapatkan pengalaman buruk dan mungkin ditolak. Tidak baik!

harsimranb
sumber
0

Ini adalah praktik yang baik untuk mengidentifikasi kolom mana yang benar-benar membutuhkan indeks dengan beberapa analisis dimuka. Ada risiko nyata penurunan kinerja secara bertahap atau tidak terduga dalam produksi karena ukuran basis data meningkat jika Anda sama sekali tidak memiliki indeks. Situasi yang ingin Anda hindari adalah di mana kueri yang biasa dijalankan memerlukan pemindaian sejumlah besar baris tabel. Ini bukan optimasi prematur untuk menambahkan indeks ke kolom kritis karena Anda memiliki banyak informasi yang diperlukan tersedia dan perbedaan kinerja potensial yang signifikan (urutan besarnya). Ada juga situasi di mana manfaat indeks kurang jelas atau lebih tergantung pada data - Anda mungkin dapat menunda memutuskan untuk beberapa kasus ini.

Beberapa pertanyaan yang perlu Anda tanyakan adalah:

  • Berapa batas desain untuk ukuran masing-masing tabel?

Jika tabel selalu kecil (katakanlah <100 baris), itu bukan bencana jika database harus memindai seluruh tabel. Mungkin bermanfaat untuk menambahkan indeks, tetapi ini membutuhkan sedikit lebih banyak keahlian atau pengukuran untuk menentukan.

  • Seberapa sering setiap query dijalankan, dan berapa waktu respons yang diperlukan?

Jika kueri dijalankan jarang dan tidak memiliki persyaratan waktu respons yang ketat (misalnya pembuatan laporan) dan jumlah baris tidak besar, maka mungkin cukup aman untuk menunda menambahkan indeks. Sekali lagi, keahlian atau pengukuran dapat membantu mengetahui apakah itu akan bermanfaat.

  • Apakah kueri mengharuskan mencari tabel dengan sesuatu selain dari kunci utama? Misalnya memfilter menurut rentang tanggal, bergabung dengan kunci asing?

Jika kueri ini sering dijalankan dan menyentuh tabel dengan banyak baris, maka Anda harus secara serius mempertimbangkan untuk menambahkan indeks terlebih dahulu. Jika Anda tidak yakin apakah ini kasus untuk kueri, Anda dapat mengisi basis data dengan jumlah data yang realistis, lalu melihat rencana kueri.

pengguna611910
sumber