it-swarm.asia

Implikasi kinerja ukuran VARCHAR MySQL

Apakah ada perbedaan kinerja dalam MySQL antara ukuran varchar? Misalnya, varchar(25) dan varchar(64000). Jika tidak, adakah alasan untuk tidak mendeklarasikan semua varchars dengan ukuran maksimal hanya untuk memastikan Anda tidak kehabisan ruangan?

46
BenV

Anda harus menyadari tradeoff 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 beberapa bentuk pemeriksaan panjang dalam semua kasus.

Imbalan lebih jelas ketika Anda melakukan dua hal:
1. Menyimpan jutaan atau miliaran baris
2. Kolom pengindeksan yang 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 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 Desain dan Tuning Basis Data MySQL melakukan sesuatu yang luar biasa pada tabel MyISAM untuk membuktikan ini. Contoh dalam buku ini melakukan sesuatu seperti berikut:

ALTER TABLE tblname ROW_FORMAT=FIXED;

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:

SELECT * FROM tblname PROCEDURE ANALYSE();

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)

30
RolandoMySQLDBA

Jawabannya sebenarnya agak rumit. Versi singkat: ada perbedaan.

  1. Saat membuat tabel sementara untuk memfilter hasil (mis. GROUP BY pernyataan), panjang penuh akan dialokasikan.

  2. Protokol kawat (mengirim baris ke klien) kemungkinan akan mengalokasikan panjang yang lebih besar.

  3. 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.

13
Morgan Tocker

Sebagian besar jawaban di utas ini adalah lima delapan tahun, ditulis sebelum InnoDB dan utf8 adalah default. Jadi, izinkan saya memulai lagi ...

Ketika kueri membutuhkan tabel sementara internal, ia mencoba menggunakan tabel MEMORY. Tetapi MEMORY tidak dapat digunakan jika

  • TEXT/BLOB kolom diambil, bahkan TINYTEXT.
  • VARCHAR lebih besar dari jumlah tertentu, mungkin 512 dalam versi saat ini.

Juga, perhatikan bahwa VARCHARs diubah menjadi CHARs. (8.0 memodifikasi ini.) Jadi, VARCHAR(255) dengan CHARACTER SET utf8 Berkembang menjadi 765 byte, terlepas dari apa yang ada di kolom. Kemudian, ini mungkin dipicu:

  • Jika tabel MEMORY menjadi lebih besar dari max_heap_table_size()tmp_table_size, Itu akan dikonversi ke MyISAM dan berpotensi tumpah ke disk.

Jadi, VARCHAR(25) lebih cenderung tetap MEMORY, jadi lebih cepat. (255) Tidak sebagus, dan (64000) Buruk.

(Di masa depan, tabel temp mungkin akan InnoDB, dan bagian dari jawaban ini perlu direvisi.)

11
Rick James

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 terlihat pada 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 memperluas 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.

6
TechieGurl

Ini pemahaman saya bahwa bidang yang lebih kecil mungkin dimasukkan dalam indeks secara langsung, sedangkan yang lebih panjang tidak bisa. Karena keterbatasan itu, jika Anda ingin agar 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.

5
jcolebrand

pastikan Anda tidak kehabisan kamar

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 boleh 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.

3
Larry Coleman