Apakah ada perbedaan kinerja dalam MySQL antara ukuran varchar? Sebagai contoh, varchar(25)
dan varchar(64000)
. Jika tidak, adakah alasan untuk tidak mendeklarasikan semua varchars dengan ukuran maksimal hanya untuk memastikan Anda tidak kehabisan ruangan?
45
Jawaban:
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 memerlukan manipulasi string lebih sedikit 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:
Kekuatan pengarah ini adalah VARCHAR untuk 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 bisa 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 di CHAR (15) dalam sekejap karena panjang alamat IP tidak akan banyak berbeda dan kompleksitas tambahan dari manipulasi string dikontrol oleh byte tambahan. Anda masih bisa melakukan PROSEDUR ANALISIS () terhadap kolom tersebut. 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)
sumber
Jawabannya sebenarnya agak rumit. Versi singkatnya: ada perbedaan .
Saat membuat tabel sementara untuk menyaring hasil (misalnya
GROUP BY
pernyataan), panjang penuh akan dialokasikan.Protokol kawat (mengirim baris ke klien) kemungkinan akan mengalokasikan panjang yang lebih besar.
Mesin penyimpanan mungkin / mungkin tidak menerapkan varchar yang tepat.
Untuk (2) saya akui protokol kawat bukanlah sesuatu yang saya kenal dengan akrab, tetapi saran umum di sini adalah mencoba dan menerapkan setidaknya beberapa upaya minimal untuk menebak panjangnya.
sumber
Sebagian besar jawaban di utas ini berusia 5 tahun, ditulis sebelum InnoDB dan utf8 adalah default. Jadi, izinkan saya memulai lagi ...
Ketika kueri membutuhkan tabel sementara internal, ia mencoba menggunakan
MEMORY
tabel. Tetapi MEMORY tidak dapat digunakan jikaTEXT
/BLOB
Kolom diambil, bahkan tidakTINYTEXT
.VARCHAR
lebih besar dari jumlah tertentu, mungkin 512 dalam versi saat ini.Juga, perhatikan yang
VARCHARs
diubah menjadiCHARs
. Jadi,VARCHAR(255)
denganCHARACTER SET utf8
ekspansi ke 765 byte, terlepas dari apa yang ada di kolom. Kemudian, ini mungkin dipicu:MEMORY
tabel menjadi lebih besar dari salah satumax_heap_table_size
atautmp_table_size
, itu akan dikonversi ke MyISAM dan berpotensi tumpah ke disk.Jadi,
VARCHAR(25)
lebih mungkin untuk tetapMEMORY
, maka lebih cepat.(255)
tidak sebagus, dan(64000)
buruk.(Di masa depan, temp tables mungkin akan ada
InnoDB
, dan bagian dari jawaban ini perlu direvisi.)sumber
Kolom varchar yang ukurannya membuat kueri di seluruh tabel lebih cenderung menggunakan tabel sementara. Menurut buku MySQL Kinerja Tinggi. Ketika pengoptimal mencoba untuk melihat apakah ia dapat menjalankan kueri ini di memori atau jika ia membutuhkan tabel temp, itu melihat ukuran baris berdasarkan definisi tabel, artinya, untuk kecepatan ia tidak mencoba melihat seberapa banyak karakter 64K Anda benar-benar menggunakan. Inilah sebabnya penulis menyarankan Anda untuk tidak merentangkan definisi itu melampaui nilai-nilai aktual yang mungkin masuk dalam kolom. Jelas, jika Anda mengatur diri sendiri untuk lebih banyak pertanyaan masuk ke tabel temp (bahkan jika ukuran data yang sebenarnya bisa muat dalam RAM) Anda sekarang telah dikenakan hukuman I / O Anda bisa menghindari.
sumber
Ini pemahaman saya bahwa bidang yang lebih kecil dapat dimasukkan dalam indeks secara langsung, sedangkan yang lebih panjang tidak bisa. Karena keterbatasan itu, jika Anda ingin string dapat diindeks, saya akan mengatakan agar mereka lebih pendek. Kalau tidak, tidak, karena keduanya sama-sama varchar maka ops seperti sortir atau perbandingan akan beroperasi dalam waktu yang sama, apakah bidangnya 25 atau MAX.
sumber
Frasa ini menyiratkan bahwa Anda mengajukan pertanyaan karena Anda tidak yakin tentang data yang akan Anda simpan dalam database. Jika itu benar, Anda akan dilayani dengan baik untuk mengetahuinya sesegera mungkin, karena Anda akan membutuhkannya untuk perencanaan kapasitas. Jika Anda mungkin mendapatkan elemen data dengan 7000 karakter, misalnya, Anda perlu tahu karena itu akan memiliki implikasi kinerja pada setiap DBMS.
Karena itu, saya lebih suka memiliki ukuran kolom yang terkait dengan konten yang diharapkan. Misalnya, nomor telepon tidak lebih dari 50 karakter, bahkan jika Anda memasukkan kode negara dan ekstensi. Demikian pula, kode pos atau kode pos kemungkinan besar akan menjadi 20 karakter atau kurang.
sumber