選擇數據類型時,在滿足業務範圍前提下,優先選用佔用空間最小、處理最簡單的類型。這不僅減少磁碟 I/O,更能縮小索引體積、加快 CPU 運算、提升緩衝區命中率。
TINYINT UNSIGNED (1 byte)SMALLINT UNSIGNED (2 bytes)INT UNSIGNED (4 bytes)BIGINT (8 bytes) 作主鍵,除非真有百億級行數。| 引擎 | 建議 | 理由 |
|---|---|---|
| MyISAM | 固定長度優先(CHAR) | 固定行長 → 位移計算 O(1)、無碎片、崩潰恢復快。代價:佔空間(尾部補空格)。 |
| InnoDB | 變長優先(VARCHAR) | 行格式統一用指標指向資料,CHAR 平均佔更多空間 → 增加 I/O。VARCHAR 節省空間更划算。 |
| MEMORY | 無差異 | 全轉為固定長度處理,CHAR/VARCHAR 同樣佔定長空間。 |
| BDB | 實測為準 | 差異極小,建議實際壓測決定。 |
例外:CHAR 最大 255 字元,超過必須用 VARCHAR 或 TEXT。
WHERE col = 'val' 直接轉為範圍查詢,無需額外 IS NOT NULL 檢查。狀態碼、性別、類型等「值集合固定、基數極低」的欄位,改為 ENUM 內部以整數儲存,比較/排序/索引極快。
SELECT * FROM tbl_name PROCEDURE ANALYSE(16, 256);
輸出每欄的建議類型(含 ENUM 建議值集合)。第二參數限制 ENUM 最大值數/長度,避免輸出過長。
OPTIMIZE TABLE(MyISAM/BDB 支援,InnoDB 重建表)。mysqldump --opt db tbl > dump.sql && mysql db < dump.sqlMD5()/SHA1()/CRC32() 存入獨立 BINARY(16/20/4) 欄位並建索引。查詢時先匹配雜湊值(精確匹配極快),再回表取大物件。不適用範圍查詢。SELECT * 不拖大物件。| 策略 | 原理 | 適用場景 |
|---|---|---|
LOAD DATA INFILE | 批量載入、單次解析、索引延遲刷新 | 首選,速度最快 |
LOAD DATA 無 LOCAL | 伺服器端直接讀檔,省網路傳輸 | 檔案已在伺服器、有 FILE 權限 |
多值 INSERT | INSERT INTO t VALUES (...),(...),...; 減少解析與索引刷新次數 | 必須用 INSERT 時 |
| 事務/鎖表批次提交 | InnoDB:START TRANSACTION...COMMIT;MyISAM:LOCK TABLES WRITE...UNLOCK TABLES | 大量 INSERT 合併索引刷新 |
DELAYED_KEY_WRITE | MyISAM 索引緩衝區延遲刷新 | 大量寫入、可容忍崩潰修復 |
壓縮協定 --compress | 減少網路傳輸量 | 慢速網路、大量資料 |
| 省略預設值欄位 | SQL 更短、解析更少 | 所有 INSERT |
| 新表先建無索引 → 載入 → 建索引 | 一次建索引比逐行維護快數量級 | MyISAM 大量初始化 |
既有表 DISABLE/ENABLE KEYS | 關閉/開啟非唯一索引更新 | MyISAM 大量追加 |
長時間 SELECT 阻塞寫入時,可採「輔助表」策略:寫入先入輔助表,定期批量合併至主表。優點:主表無鎖爭用、合併時索引只刷一次。缺點:新資料有延遲可見性。適用於 Web 存取日誌等非即時業務。
若表無「中間空洞」(無 DELETE/UPDATE 縮短行),MyISAM 允許 INSERT 與 SELECT 同時進行,無需輔助表。啟用條件:concurrent_insert=1(預設)。