informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Daftar isi
Indeks apa yang dimiliki MySQL?
Apa perbedaan antara indeks normal dan indeks unik?
Bidang apa yang biasanya kita pilih untuk membuat indeks?
Apakah lebih banyak indeks lebih baik?
Apa prinsip pencocokan paling kiri?
Urutan kueri prinsip pencocokan paling kiri
Apa itu penekanan indeks? Ditambahkan di MySQL5.6 untuk mengoptimalkan kueri data
Bagaimana cara membuat indeks di mana a>1 dan b=2 dan c <3?
(A,B,C) indeks gabungan pilih * dari tbn di mana a=? dan b di (?,?) dan c>?
Bagaimana cara membuat indeks gabungan di mana a>100 dan b=100 dan c=123 diurutkan berdasarkan d?
Saya mengetahui bahwa MySQL memilikinyakunci utamaIndeks, indeks unik, indeks biasa, indeks awalan,Indeks serikat pekerjaJenis indeks ini.
Mesin Innodb mengharuskan setiap tabel database harus memiliki akunci utamaindeks,Nilai kolom indeks tidak diperbolehkannilai nol。Misalnya, bidang id dalam tabel adalah indeks kunci utama
Indeks unik: Pastikan keunikan setiap baris data di kolom data, tetapi izinkan nilai null.
KemudianUntuk field yang sering ditanyakan, kita dapat membuat indeks normal untuk field ini.,Jika ada beberapa bidang, Anda dapat mempertimbangkan untuk membuatnyaIndeks serikat pekerja,menggunakanCakupan indeksFitur meningkatkan efisiensi kueri.
Untuk teks panjang, string, dan jenis bidang lainnya, seperti judul artikel, nama produk, dll., kami hanya dapat mengindeks bagian awalan bidang tersebut, yaituBuat indeks awalan untuk mengurangi ruang penyimpanan indeks.
Indeks unik mungkin sedikit lebih cepat ketika menanyakan satu nilai karena dapat menghentikan pencarian setelah menemukan kecocokan pertama.
Untuk operasi penyisipan dan pembaruan, indeks normal mungkin sedikit lebih cepat karena tidak memerlukan pemeriksaan keunikan.
Nilai kolom indeks biasa dapat diulang, tetapi nilai kolom indeks unik harus unik. Saat kita memasukkan nilai berulang ke dalam indeks unik, kesalahan akan dilaporkan karena batasan keunikan.
Menurut sayaKinerja update indeks biasa akan lebih baik, karena ketika indeks biasa diupdate, jika halaman data diupdate tidakPenyimpanan Jika demikian, Anda dapat langsung menyimpan operasi pembaruan dalam cache perubahan, dan operasi pembaruan akan selesai. (tidak diperlukan pemeriksaan keunikan)
Tetapi,Indeks unik harus memiliki batasan unik. Jika halaman data yang diperbarui tidak ada diPenyimpananJika demikian, Anda perlu membaca halaman data terkait dari disk ke memori untuk menentukan apakah ada konflik. Ini akan melibatkan pengacakan disk.SayaMengakses.
Karena indeks biasa dapat menggunakan fitur buffer perubahan, pembaruan indeks biasa lebih cepat dibandingkan indeks unik.Mengurangi akses disk acak, sehingga kinerja pembaruan lebih baik
Saat InnoDB membuat indeks berkerumun, ia akan memilih kolom berbeda sebagai indeks berdasarkan skenario berbeda:
Jika ada kunci utama, kunci utama akan digunakan sebagai kunci indeks dari indeks berkerumun secara default.
Jika tidak ada kunci utama, pilihYang pertama tidak mengandung nilai BATALSatu-satunya kolom adalah sebagaiindeks berkerumunkunci indeks
Jika salah satu hal di atas tidak ada, InnoDB akan secara otomatis menghasilkan kolom rowid kenaikan otomatis implisit sebagai kunci indeks dari indeks berkerumun.
Skenario di mana pengindeksan dapat diterapkan:
Bidang memiliki batasan keunikan, seperti kode produk
Bidang yang sering digunakan dalam kondisi kueri WHERE, yang dapat meningkatkan kecepatan kueri seluruh tabel. Jika kondisi kueri bukan bidang, indeks gabungan dapat dibuat
Bidang yang sering digunakan di GROUPBY dan ORDER BY, sehingga tidak perlu melakukan pengurutan lagi pada saat pencarian, karena record pada B+ Tree sudah terurut semua setelah indeks dibuat.
Skenario tidak cocok untuk pengindeksan
Bidang yang tidak digunakan dalam kondisi WHERE, GROUP BY, ORDER BY, nilai indeks dapat diposisikan dengan cepat. Jika bidang tidak dapat diposisikan, biasanya tidak perlu membuat indeks, karena indeks akan menempati ruang fisik.
Bidang dengan pembedaan rendah , tidak perlu membuat indeks, misalnya bidang gender hanya berisi laki-laki dan perempuan. Jika catatan laki-laki dan perempuan tersebar merata di tabel database, maka nilai mana pun yang dicari, separuh datanya boleh. didapat.Dalam kasus ini, lebih baik tidak mengindeks karena Bahasa Indonesia: Bahasa Indonesia: Bahasa Indonesia: Bahasa Indonesia: MySQLMasih ada satupengoptimal kueri, ketika pengoptimal kueri menemukan bahwa nilai tertentu muncul dalam persentase baris data yang tinggi dalam tabel, biasanya pengoptimal kueri akan mengabaikan indeks dan melakukanPemindaian tabel lengkap。
Bidang yang sering diperbarui, misalnya, jangan mengindeks saldo pengguna proyek e-niaga karena bidang indeks sering diubah.untuk mempertahankan B+Pohonketeraturan, maka diperlukan pembangunan kembali indeks secara sering, dan proses ini akan mempengaruhi kinerja database.
Tidak disarankan untuk menggunakan nilai yang tidak diurutkan(seperti kartu ID, UUID) sebagai indeks, ketika kunci utama tidak pasti, akan menyebabkan seringnya pemisahan node daun dan fragmentasi penyimpanan disk.
Tabel datanya lebih kecil: Ketika jumlah data dalam tabel kecil, atau ketika kueri memerlukan pemindaian sebagian besar data dalam tabel, pengoptimal database dapat memilih pemindaian tabel penuh daripada menggunakan indeks. Dalam hal ini, biaya pemeliharaan indeks mungkin lebih besar daripada perolehan kinerja.
Tidak, meskipun indeks dapat meningkatkan efisiensi kueri, membuat satu indeks lagi berarti indeks pohon B+ baru akan dihasilkan, yang akan memakan ruang penyimpanan. Terutama ketika jumlah data tabel sangat besar, indeks akan memakan lebih banyak ruang.
Semakin banyak indeks maka kinerja penulisan database akan menurun, karena setiap kali Anda menambah, menghapus, atau mengubah tabel, Anda perlu menjaga urutan setiap indeks pohon B+.
Saya telah menggunakan metode pengoptimalan ini
Untuk SQL yang perlu mengkueri data di beberapa bidang, kita bisa membuatnyaIndeks serikat pekerja, jadi metode kuerinya menjadimeliputi indeks, menghindari dukungan tabel dan mengurangi sejumlah besar operasi I/O.
kitakunci utamaIndeks sebaiknya meningkatkan nilai, karena indeks kita menyimpan data secara berurutan, jika nilai kunci utama adalah nilai acak, dapat menyebabkan pemisahan halaman. Pemisahan halaman akan menyebabkan sejumlah besar fragmen memori, sehingga struktur indeks tidak akan kompak, yang mana akan terjadi mempengaruhi efisiensi kueri.
kita inginkanHindari menuliskan kegagalan indeks Bahasa Indonesia: SQL Pernyataan, seperti tidak melakukan pencocokan fuzzy kiri atau kiri pada kolom indeks, tidak melakukan perhitungan, fungsi, dan mengetikkan operasi konversi pada indeks untuk menggunakan indeks gabungan dengan benar, Anda harus mengikuti prinsip pencocokan paling kiri, dll.Pada klausa WHERE, jika kolom kondisi sebelum OR merupakan kolom indeks dan kolom kondisi setelah OR bukan kolom indeks, maka indeks akan gagal.
Gunakan tidak sama dengan (
<>
) atau operator NOT: Operator ini biasanya membuat indeks tidak valid karena memindai seluruh tabel.Operator OR: Jika OR digunakan dalam kondisi kueri, dan kondisi di kedua sisi OR melibatkan indeks yang berbeda, maka indeks ini tidak boleh digunakan.
menggunakan
OR
operator, jikaOR
Kondisi di kedua sisi melibatkan indeks yang berbeda, dan mesin database tidak dapat menggunakan beberapa indeks secara bersamaan untuk mengoptimalkan kueri dalam banyak kasus.IniKarenaOR
Operator hanya perlu memenuhi ketentuan di kedua sisi, yang meningkatkan kompleksitas pengoptimalan kueri.
Indeks untuk beberapa string besar, kita dapat mempertimbangkan untuk menggunakanindeks awalanHanya bagian awalan kolom indeks yang diindeks untuk menghemat ruang penyimpanan indeks dan meningkatkan kinerja kueri.
Indeks paling baik diatur ke NOT BATAL : Untuk memanfaatkan indeks dengan lebih baik, kolom indeks harus disetel ke batasan NOT NULL. Ada dua alasan:
Kehadiran NULL pada kolom indeks akan membuat pemilihan indeks pengoptimal menjadi lebih rumit, sehingga lebih sulit untuk mengoptimalkan operasi seperti penghitungan.
Nilai NULL adalah nilai yang tidak berarti, tetapi akan menempati ruang fisik.Setidaknya 1 byte ruang akan digunakan untuk menyimpan NULL daftar nilai
TIDAK.
aku telah belajarMeskipun kueri menggunakan indeks, kueri tersebut mungkin tidak menggunakan indeks.
Misalnya: ketika pernyataan kueri kami melakukan pencocokan fuzzy kiri, penghitungan ekspresi, fungsi, dan operasi konversi tipe implisit pada bidang indeks, maka pernyataan kueri tidak dapat melewati indeks, dan metode kueri menjadi pemindaian tabel penuh.
Dan kami menggunakanIndeks serikat pekerjaSaat melakukan kueri, jika prinsip pencocokan paling kiri tidak diikuti, kegagalan indeks juga akan terjadi.。
Pengoptimalnya adalahPilih metode kueri berdasarkan pertimbangan biaya, saat menggunakan indeks sekunder untuk kueri, pengoptimal akan menghitung biaya pengembalian tabel dan biaya pemindaian tabel penuh. Jika biaya pengembalian tabel terlalu tinggi, pengoptimal akan memilih untuk tidak menggunakan indeks, tetapi menggunakan pemindaian tabel penuh.
Tidak akan mencapai indeks.
Karena mysql sedang menemuiPerbandingan string dan angkaakan terjadi kapankonversi tipe implisit, akanUbah objek string menjadi angka, proses konversi ini sebenarnya melibatkanfungsi . Dalam kueri yang Anda sebutkan, bidang tanggal adalah string, jadi ketika konversi tipe implisit terjadi, itu akan diterapkan ke bidang indeks tanggal. Jika penghitungan fungsi dilakukan pada indeks, indeks akan menjadi tidak valid.
Untuk kolom indeks bertipe integer, misalnya
id
Kolom yang nilainya disimpan langsung di indeks tanpa terjadi penghitungan fungsi.Ini berarti menggunakan dalam kueriid
Saat mencocokkan, tidak perlu melakukannyaid
Lakukan penghitungan atau konversi fungsional apa pun dan cukup bandingkan nilai bilangan bulat.
Saya mengetahui bahwa MySQL8.0 dapat menambahkan kolomindeks fungsi, fitur baru ini dapat mengatasi masalah kegagalan indeks saat menggunakan fungsi pada indeks.
Fitur baru lainnya adalahindeks lewati pemindaian, Sebelum versi 5.7, saat menggunakan indeks gabungan, jika prinsip pencocokan paling kiri tidak terpenuhi, kegagalan indeks akan terjadi. Namun, setelah fitur pemindaian lewati indeks diperkenalkan di 8.0, indeks gabungan masih dapat digunakan meskipun prinsip pencocokan paling kiri. tidak diikuti.
Misalkan ada indeks gabungan a (a, b, c). Urutan penyimpanannya adalah mengurutkan berdasarkan a terlebih dahulu, lalu mengurutkan berdasarkan b jika a sama, lalu mengurutkan berdasarkan c jika b sama. Karena fitur ini, saat menggunakan indeks gabungan, terdapat prinsip pencocokan paling kiri. Aturan spesifiknya adalah:
Indeks gabungan MySQL akan dimulai dariKolom indeks paling kiri mulai cocok dengan kondisi kueri, lalu cocok secara berurutan dari kiri ke kanan. Jika kondisi kueri tidak menggunakan kolom, maka semua kolom di sebelah kanan kolom tidak dapat diindeks.
Ketika kolom digunakan dalam kondisi kueri,Namun, nilai kolom ini berisi kueri rentang, dan bidang kueri rentang dapat digunakanIndeks serikat pekerja, tetapi indeks gabungan tidak dapat digunakan pada kolom di belakang kolom kueri rentang.
Oleh karena itu, ketika kita menggunakan indeks gabungan, kita harus mematuhi prinsip pencocokan paling kiri, jika tidak, beberapa bidang indeks mungkin tidak dapat diindeks.
palingMasukkan bidang dengan perbedaan yang lebih besarIndeks serikat pekerjapaling kiri, bermanfaatTingkatkan efek pemfilteran indeks, bidang seperti UUID lebih cocok untuk diindeks atau diberi peringkat di bagian atas kolom indeks gabungan.
Jika bidang dengan diskriminasi rendah ditempatkan di sisi paling kiri indeks gabungan, hal ini dapat menyebabkan pengoptimal kueri memilih pemindaian tabel lengkap daripada menggunakan indeks.
Prinsip pencocokan paling kiri dari indeks gabungan, inSaat menemukan kueri rentang (seperti >, <), pencocokan akan berhenti, yaitu, bidang kueri rentang dapat menggunakan indeks gabungan, namun bidang di belakang bidang kueri rentang tidak dapat menggunakan indeks gabungan.Namun, untuk empat rentang kueri >=, <=, BETWEEN, dan pencocokan awalan sejenisnya, pencocokan tidak akan berhenti.
Di MySQL, BETWEEN berisi nilai batas nilai1 dan nilai2, mirip dengan >= dan =<.
Tautan referensi https://zhuanlan.zhihu.com/p/573138586
select * from T where c=1 and a=2 and b=3;
abc dapat diindeks karena Urutan bidang kondisi kueri tidak terpengaruh, pengoptimal MySQL akan membantu kita menyesuaikan urutan kueri bidang, sehingga juga mematuhi prinsip pencocokan paling kiri.
Penekanan indeks dapat berkurangindeks sekunderOperasi pengembalian tabel selama kueri meningkatkan efisiensi kueri karena hal itu akan terjadi Lapisan server bertanggung jawab atas beberapa hal yang ditangani oleh lapisan mesin penyimpanan.Pergi untuk menghadapinya.
Ketika optimasi push-down tanpa kondisi indeks digunakan, mesin penyimpanan mengambil data melalui indeks dan kemudian mengembalikannya ke Server MySQL.Server MySQL Buat penilaian tentang kondisi filter.
Saat menggunakan optimasi push-down kondisi indeks, jika ada kondisi penilaian tertentu untuk kolom yang diindeks, Server MySQL akan mendorong bagian dari kondisi penilaian ini ke mesin penyimpanan, dan kemudian mesin penyimpanan akan menilai apakah indeks memenuhi kondisi yang dilewati oleh Server MySQL. Hanya jika indeks memenuhi ketentuan, data akan diambil dan dikembalikan ke server MySQL.
Pengoptimalan pushdown kondisi indeks dapat mengurangi frekuensi mesin penyimpanan menanyakan tabel yang mendasarinya, dan juga dapat menguranginya Bahasa Indonesia: Bahasa Indonesia: Bahasa Indonesia: Bahasa Indonesia: MySQL Berapa kali server menerima data dari mesin penyimpanan.
select * from t_user where age > 20 and reward = 100000;
Buat indeks gabungan (abc), (acb), (ab), (ac), hanya indeks kaleng
Buat indeks gabungan (cab), (cba), (ca), (cb), hanya c yang dapat mengindeks
Buat indeks gabungan (ba), b dan a dapat diindeks
Buat indeks gabungan (bc), b dan c dapat diindeks
buat(kembali) Indeks serikat pekerja, b dan a keduanya dapat diindeks, tetapi lebih lambat dari (kembali) indeks gabungan memiliki satu manfaat lagi, bidang c bisapenekanan indeks, akan mengurangi jumlah pengembalian tabel;
membuat(bca) Indeks serikat pekerja, b dan c dapat diindeks, tetapi memiliki satu keunggulan lebih dari indeks gabungan (bc), bidang a dapatpenekanan indeks, akan mengurangi jumlah pengembalian tabel;
select * from tbn where a=? and b in (?,?) and c>?
Apakah akan diindeks?Kueri ini akan menggunakan indeks gabungan (A,B,C)
, karena kondisinya berdasarkan kolom indeks A
、B
、C
Pesanan datang, yang merupakan skenario penggunaan ideal.
untuk A=?
: Kondisi ini sama persis. MySQL akan menggunakan indeks untuk menemukan kondisi yang memenuhi kondisi tersebut. A=?
rekaman dari.
untuk B IN (?, ?)
: Kondisi ini menentukan B
Kolom dapat mengambil dua kemungkinan nilai. MySQL akan menggunakan indeks untuk menemukan semua kecocokanA=?
DanB
Kolom adalah catatan dengan salah satu dari dua nilai ini.
untuk C>?
: Kondisi ini adalah kueri rentang.sudah berdasarkanA
DanB
Berdasarkan filter, MySQL akan terus menggunakan indeks untuk mencariC
Catatan dengan nilai kolom lebih besar dari nilai yang ditentukan.
Menurut sayaMendirikan bcda dalam urutanIndeks serikat pekerjaLebih baik, saat ini bidang b dan c dapat diindeks, dand dapat menggunakan pengurutan indeks untuk menghindari pengurutan file (penyortiran tambahan), meskipun bidang a terakhir tidak dapat diindeks (a rusak), bidang tersebut dapat diturunkan menggunakan indeks untuk mengurangi jumlah pengembalian tabel.
Urutan indeks gabungannya adalah nama terlebih dahulu, kemudian umur. Secara struktural, diurutkan berdasarkan nama terlebih dahulu, kemudian diurutkan berdasarkan umur jika namanya sama.Oleh karena itu, pengoptimal harus mencocokkan nama terlebih dahulu. Nama adalah kueri fuzzy yang tepat saat ini, dan kegagalan indeks tidak akan terjadi, sehingga SQL ini dapat menggunakan pengindeksan bersama.
Secara khusus, hanya nama yang dapat diindeksSetelah name right fuzzy query, nilai pada field age tidak berurutan, sehingga age tidak dapat diindeks, tetapi age dapat diindeks.penekanan indeks。
Bidang kueri terakhir adalah id dan nama. Kedua bidang ini dapat ditemukan pada indeks gabungan, sehingga tidak perlu mengembalikan tabel. Ini adalah kueri cakupan indeks.
Nama kueri fuzzy kanan adalah kueri rentang, dan bidang berikut tidak dapat diindeks