Saya memiliki kolom yang diindeks yang menyimpan hash MD5. Dengan demikian, kolom akan selalu menyimpan nilai 32 karakter. Untuk alasan apa pun, ini diciptakan sebagai varchar daripada char. Apakah sepadan dengan kesulitan memigrasi basis data untuk mengubahnya menjadi char? Ini di MySQL 5.0 dengan InnoDB.
mysql
performance
innodb
varchar
Jason Baker
sumber
sumber
Jawaban:
Pertanyaan serupa diajukan sebelumnya
Implikasi kinerja dari ukuran MySQL VARCHAR
Ini kutipan dari jawaban saya
Anda harus menyadari pengorbanan menggunakan CHAR vs VARCHAR
Dengan bidang CHAR, apa yang Anda alokasikan adalah persis apa yang Anda dapatkan. Misalnya, CHAR (15) mengalokasikan dan menyimpan 15 byte, tidak peduli bagaimana karakter yang Anda tempatkan di bidang. Manipulasi string sederhana dan mudah karena ukuran bidang data benar-benar dapat diprediksi.
Dengan bidang VARCHAR, Anda mendapatkan cerita yang sama sekali berbeda. Misalnya VARCHAR (15) sebenarnya mengalokasikan secara dinamis hingga 16 byte, hingga 15 untuk data dan, setidaknya, 1 byte tambahan untuk menyimpan panjang data. Jika Anda memiliki string 'halo' untuk menyimpan yang akan mengambil 6 byte, bukan 5. Manipulasi string harus selalu melakukan semacam pemeriksaan panjang dalam semua kasus.
Imbalan lebih jelas ketika Anda melakukan dua hal: 1. Menyimpan jutaan atau miliaran baris 2. Kolom pengindeksan yang baik CHAR atau VARCHAR
TRADEOFF # 1 Jelas, VARCHAR memegang keuntungan karena data panjang variabel akan menghasilkan baris yang lebih kecil dan, dengan demikian, file fisik yang lebih kecil.
TRADEOFF # 2 Karena bidang CHAR membutuhkan lebih sedikit manipulasi string karena lebar bidang tetap, pencarian indeks terhadap bidang CHAR rata-rata 20% lebih cepat daripada bidang VARCHAR. Ini bukan dugaan saya. Buku MySQL Database Design and Tuning melakukan sesuatu yang luar biasa pada tabel MyISAM untuk membuktikan ini. Contoh dalam buku ini melakukan sesuatu seperti berikut:
Arahan ini memaksa semua VARCHAR berperilaku sebagai CHAR. Saya melakukan ini di pekerjaan saya sebelumnya pada tahun 2007 dan mengambil meja 300GB dan mempercepat pencarian indeks sebesar 20%, tanpa mengubah apa pun. Ini berfungsi seperti yang dipublikasikan. Namun, itu memang menghasilkan tabel hampir dua kali lipat, tetapi itu hanya kembali ke tradeoff # 1.
Anda dapat menganalisis data yang disimpan untuk melihat apa yang direkomendasikan MySQL untuk definisi kolom. Jalankan saja berikut ini di tabel mana saja:
Ini akan melintasi seluruh tabel dan merekomendasikan definisi kolom untuk setiap kolom berdasarkan data yang dikandungnya, nilai bidang minimum, nilai bidang maksimum, dan sebagainya. Terkadang, Anda hanya perlu menggunakan akal sehat dengan merencanakan CHAR vs VARCHAR. Ini adalah contoh yang bagus:
Jika Anda menyimpan alamat IP, mask untuk kolom seperti itu paling banyak 15 karakter (xxx.xxx.xxx.xxx). Saya akan melompat tepat
CHAR(15)
dalam sekejap karena panjang alamat IP tidak akan terlalu bervariasi dan kompleksitas manipulasi string yang dikendalikan oleh byte tambahan. Anda masih bisa melakukanPROCEDURE ANALYSE()
terhadap kolom seperti itu. Bahkan mungkin merekomendasikan VARCHAR. Uang saya masih di CHAR atas VARCHAR dalam hal ini.Masalah CHAR vs VARCHAR hanya dapat diselesaikan melalui perencanaan yang tepat. Dengan kekuatan besar datang tanggung jawab besar (klise tapi benar).
MEMPERBARUI
Ketika datang ke MD5, perhitungan
strlen
internal harus dihilangkan ketika mengganti seluruh format baris. Tidak perlu mengubah definisi bidang.Jika kunci MD5 adalah satu-satunya VARCHAR yang ada, saya akan menggunakannya dan mengonversi format baris tabel menjadi tetap . Jika ada jumlah signifikan bidang VARCHAR lain yang hadir, mereka akan mendapat manfaat juga. Sebagai gantinya, tabel akan berkembang menjadi sekitar dua kali ukurannya. Tetapi kueri harus mempercepat sekitar 20% lebih tanpa penyetelan tambahan.
sumber
bit
danbinary
?Sepertinya Anda akan menghemat 1 byte per nilai atau sekitar 3% dengan mengonversi ke a
char
. Mungkin tidak layak jika Anda menyimpan MD5 dalam hex - Anda bisa menghemat 50% dengan menggunakanbinary
gantinya.Terima kasih kepada Ovais (lihat komentar) untuk menunjukkan bahwa
char(32)
dapat menggunakan lebih dari 32 byte jika Anda menggunakan rangkaian karakter multibyte.Terima kasih kepada Rick James untuk menunjukkan bahwa Anda harus menggunakan
unhex
fungsi untuk mengubah string hex menjadi biner:db <> biola di sini
sumber
binary
- atau apakah saya salah paham?BINARY
melakukan sangat sedikit kecuali Anda juga menggunakannyaUNHEX()
. Artinya, Anda dapat menyimpanUNHEX(MD5(x))
menjadi 16-byteBINARY(16)
untuk menghemat ruang yang signifikan atas menyimpanMD5(x)
ke dalamCHAR(32) CHARACTER SET ascii
.Tidak ada gunanya mengubah pendapat saya. Jika Anda melihat dokumentasi di sini harus menggambarkan perbedaan antara keduanya. Dalam skenario penggunaan Anda, yang satu tidak benar-benar menawarkan manfaat yang signifikan di atas yang lain kecuali Anda benar-benar khawatir tentang sedikit biaya tambahan terkait dengan ukuran baris.
http://dev.mysql.com/doc/refman/5.0/id/char.html
Perhatikan juga komentar pertama pada dokumentasi yang saya tautkan di atas ... "CHAR hanya akan mempercepat akses Anda jika seluruh catatan berukuran tetap. Artinya, jika Anda menggunakan objek ukuran variabel apa pun, Anda sebaiknya membuat semuanya ukuran variabel. Anda tidak mendapatkan kecepatan dengan menggunakan CHAR di tabel yang juga berisi VARCHAR "
sumber