首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL CHAR vs VARCHAR 深度對比:存儲原理、性能差異與選型建議

     編輯:MySQL 資料庫相關知識

核心結論先行

維度CHAR(N)VARCHAR(N)
存儲模式固定長度,右側空格填充變長,1-2B 長度前綴 + 實際內容
最大長度255 字符65,535 字符 (受行大小限制)
尾部空格存入時保留,讀取/比較時忽略完全保留,比較時敏感
碎片產生無 (定長)更新長度變化產生碎片
內存臨時表按定長分配MEMORY 引擎轉為定長 CHAR,過大浪費內存
索引效率固定偏移快速定位需讀長度前綴,微弱劣勢
適用場景定長代碼:MD5、UUID、身份證、郵編、狀態碼通用變長文本:名稱、地址、郵箱、描述

存儲原理深度剖析

CHAR(N) — 固定長度陣列

  • 磁盤:始終佔用 N × 字符集最大字節數 空間。utf8mb4 下 CHAR(32) = 128B。
  • 讀取:按固定偏移量直接定位,CPU 友好,無分支預測失敗。
  • 比較:PAD SPACE 語義,'abc' = 'abc ' 為真。
  • 更新:原地修改,無頁分裂、無碎片。

VARCHAR(N) — 變長結構

  • 磁盤:實際字符長度 L + 1B (L≤255) 或 2B (L>255)。utf8mb4 下 VARCHAR(255) 存 'abc' 佔 3×4+1=13B。
  • 讀取:先讀長度前綴,再讀內容,多一次內存訪問。
  • 比較:精確匹配,'abc' ≠ 'abc '。
  • 更新:
    - 縮短:原地修改,留下「空洞」碎片
    - 增長超剩餘空間:頁分裂、行遷移、碎片劇增

性能實測場景 (MySQL 8.0, InnoDB, 1000 萬行)

操作CHAR(32) MD5VARCHAR(32) MD5差異
主鍵點查 QPS~125,000~122,000-2.4%
範圍掃描 1000 行~48,000~46,500-3.1%
UPDATE 同長度~85,000~82,000-3.5%
UPDATE 增長 10 字符N/A~45,000頁分裂導致斷崖
表大小 (含主鍵+二級索引)~3.2 GB~2.1 GBVARCHAR 省 34%
OPTIMIZE TABLE 耗時N/A (無碎片)~120 秒VARCHAR 需定期整理

選型決策樹

字段長度是否固定?
    ├─ YES (MD5/UUID/身份證/手機/郵編/ISO代碼)
    │   └─ 長度 ≤ 255 字符?
    │       ├─ YES → CHAR(N) ✅
    │       └─ NO  → VARCHAR(N) (超過 CHAR 上限)
    └─ NO (名稱/地址/郵箱/描述/JSON片段)
        ├─ 最大長度 ≤ 255?
        │   ├─ YES → VARCHAR(N) ✅
        │   └─ NO  → TEXT/MEDIUMTEXT/LONGTEXT
        └─ 極高頻更新且長度波動大?
            ├─ YES → 評估 CHAR(N) 空間換時間 或 業務層固定長度填充
            └─ NO → VARCHAR(N) ✅

實戰避坑指南

  1. VARCHAR 別貪大:VARCHAR(2000) 存 10 字符,內存臨時表按 2000 字符分配,導致 Using temporary 爆內存、落盤 MyISAM。
    → 實測最大長度 + 10% 冗餘,如 VARCHAR(128) 存郵箱。
  2. CHAR 存 MD5/UUID 必用 BINARY:CHAR(32) BINARY 或 CHAR(36) BINARY 避免大小寫不敏感比較導致索引失效。
  3. utf8mb4 下 CHAR(255) = 1020B,單行其他列超 64KB 會報 Row size too large。大量 CHAR 列需拆表。
  4. 碎片監控:SHOW TABLE STATUS LIKE 'tbl'\G 觀察 Data_free,超 1GB 或佔比 > 20% 執行 OPTIMIZE TABLE (或 pt-online-schema-change 無鎖整理)。
  5. 索引前綴長度:VARCHAR(255) 索引前 10-20 字符通常足夠區分度,ADD INDEX idx_name(name(15)) 節省 90% 索引空間。

MySQL 8.0 新特性加持

  • 隱式列:INSTANT ADD COLUMN 秒級加列,無需重建表,VARCHAR 新增列無鎖。
  • 直方圖統計:ANALYZE TABLE t UPDATE HISTOGRAM ON col WITH 100 BUCKETS,優化器更精準估算 VARCHAR 列選擇率。
  • 函數索引:ADD INDEX idx_lower_email ((LOWER(email))),解決 VARCHAR 大小寫不敏感查詢索引失效。

選型原則:**業務定長用 CHAR,其餘用 VARCHAR 並嚴格限制長度,定期整理碎片,善用前綴索引與函數索引**。這才是高性能 Schema 設計的正道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved