MySQL Innodb數據庫性能實踐——VARCHAR vs CHAR
學過數據庫理論的讀者,都應該還記得關於CHAR和VARCHAR的性能對比:CHAR比VARCHAR更快,因為CHAR是固定長度的,而VARCHAR需要增加一個長度標識,處理時需要多一次運算。
針對這種情況,我做了一下基準測試,基準測試環境如下:
【硬件配置】
硬件 |
配置 |
CPU |
Intel(R) Xeon(R) CPU E5620 主頻2.40GHz, 物理CPU 2個,邏輯CPU 16個 |
內存 |
24G(6塊 * 4G DDR3 1333 REG) |
硬盤 |
300G * 3個,SAS硬盤 15000轉,無RAID,有RAID卡,且開了回寫功能 |
OS |
RHEL5 |
MySQL |
5.1.49/5.1.54 |
配置項 |
配置 |
innodb_buffer_pool_size |
18G |
innodb_log_file_size |
200M |
innodb_log_files_in_group |
3 |
sync_binlog |
100 |
innodb_flush_log_at_trx_commit |
2 |
VARCHAR平均長度200,CHAR長度250,其它配置如下:
配置項 |
配置 |
記錄數 |
1000萬,2000萬,5000萬,1億 |
存儲引擎 |
Innodb |
行格式 |
compact |
性能測試結果如下:
【查詢】
【插入】
【更新】
更新時VARCHAR也是隨機長度
【刪除】

測試結果展現了一個與理論不太相符的現象:當表大小小於Innodb buffer pool時,CHAR和VARCHAR沒有差別,而在表大小大於Innodb buffer pool時,VARCHAR性能反而更高!這是為什麼呢?
首先,性能是綜合硬件、配置、表記錄數、業務模型等多種因素綜合後的結果,單一因素的差異,對整體來說可能幾乎沒有影響;
例如,執行一個操作需要100ms,而CHAR 比 VARCHAR性能上隻快了1微秒,那麼最終的性能就不會有影響。
這就是當Innodb buffer pool足夠大時,CHAR 和VARCHAR沒有差別的原因。
再次,理論上CHAR比VARCHAR快的根本原因是站在CPU的角度來說的,但性能是綜合各種因素後的最終結果,當Innodb buffer pool小於表大小時,"磁盤讀寫"成為了性能的關鍵因素,而VARCHAR更短,因此性能反而比CHAR高。
最後,有朋友可能會認為,VARCHAR更新時如果新的數據比舊的數據要長,可能需要移動數據,導致性能更低;從實測結果來看,這種操作對最終的性能也是沒有明顯影響的。可能是因為Innodb采用頁管理數據,數據移動是先在內存裏完成,再寫到磁盤,因此數據即使移動也很快。
【應用技巧】
基於以上測試結果和分析,我個人認為一般情況下優先使用VARCHAR,特別是字符串的平均長度比最大長度要小很多的情況;
當然,如果你的字符串本來就很短,例如隻有10個字符,那麼就優先選CHAR了。
附:
1)有興趣的朋友可以推斷一下:為什麼測試結果中10KW的表性能,VARCHAR比CHAR快大約20%?
2)測試數據隻為對比用,不代表一般情況下MySQL的性能就這麼高,因為為了能夠對比,測試時做了很多準備工作,測試操作也是比較特殊的。
最後更新:2017-04-02 06:52:12