// ❌ 緩存失效:CURDATE() 每次結果不同
$r = mysql_query("SELECT username FROM user WHERE signup_date >= CURDATE()");
// ✅ 緩存生效:PHP 端計算日期常量
$today = date("Y-m-d");
$r = mysql_query("SELECT username FROM user WHERE signup_date >= '$today'");
原理:NOW()、RAND()、CURDATE() 等非確定性函數導致查詢緩存繞過。
關注 type(至少 range)、key(用上預期索引)、rows(預估掃描行數)、Extra(避開 Using temporary/filesort)。
// ❌ 全表掃描
$r = mysql_query("SELECT * FROM user WHERE state='Alabama'");
// ✅ 找到即停
$r = mysql_query("SELECT 1 FROM user WHERE state='Alabama' LIMIT 1");
LIKE 'abc%' 可用索引,LIKE '%abc%' 需全文索引或 ES。
-- ❌ 類型不匹配導致隱式轉換,索引失效 JOIN ON users.state(CHAR) = companies.state(INT) -- ✅ 同類型、同編碼、雙側索引
// ❌ 全表賦隨機數排序,災難性性能
$r = mysql_query("SELECT username FROM user ORDER BY RAND() LIMIT 1");
// ✅ 兩步法:先 COUNT 再隨機 OFFSET
$r = mysql_query("SELECT COUNT(*) FROM user");
$d = mysql_fetch_row($r);
$rand = mt_rand(0, $d[0]-1);
$r = mysql_query("SELECT username FROM user LIMIT $rand, 1");
只取需要的列,減少 IO、網絡、內存、覆蓋索引機會增加。
INT UNSIGNED AUTO_INCREMENT PRIMARY KEY。業務鍵(用戶名/身份證)加唯一索引,不做主鍵。關聯表除外。
內部存儲為 TINYINT,極致緊湊。PROCEDURE ANALYSE() 會建議轉 ENUM。
基於實際數據分佈推薦類型,僅作參考,結合業務擴展性判斷。
NULL 額外佔用位圖空間,增加比較複雜度(三值邏輯)。
$stmt = $mysqli->prepare("SELECT username FROM user WHERE state=?");
$stmt->bind_param("s", $state);
$stmt->execute();
$stmt->bind_result($username);
$stmt->fetch();
單次解析多次執行,二進制協議傳輸,原生防注入。
$r = mysql_unbuffered_query("SELECT * FROM huge_table");
while ($row = mysql_fetch_assoc($r)) { /* 流式處理 */ }
不佔用客戶端內存緩存全量結果,首行即可處理。限制:需讀完或 free_result 才能執行下一查詢。
$r = "UPDATE users SET ip=INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE id=$uid";
4 字節定長,比 VARCHAR(15) 省空間、比較快。PHP 對應 ip2long()/long2ip()。
全定長列表(無 VARCHAR/TEXT/BLOB)便於定位行偏移,易緩存、易恢復。權衡:空間換時間。垂直分表將變長列拆出。
while (true) {
mysql_query("DELETE FROM logs WHERE log_date <= '2019-01-01' LIMIT 10000");
if (mysql_affected_rows() == 0) break;
usleep(50000); // 讓出 CPU,緩解鎖衝突
}
TINYINT < SMALLINT < MEDIUMINT < INT < BIGINT。日期無時間用 DATE 不用 DATETIME。預留增長空間但勿過度。
| 場景 | 推薦引擎 | 理由 |
|---|---|---|
| 核心業務(事務、高併發、外鍵) | InnoDB | 行鎖、MVCC、崩潰恢復 |
| 純讀/讀多寫少/日志/統計/全文搜索(舊版) | MyISAM | 讀快、COUNT(*)瞬時、文件級備份 |
延遲加載導致大量微查詢。批量操作用事務合併。推薦 Doctrine、Eloquent。
mysql_pconnect() 理論復用連接,實際易導致連接數耗盡、內存洩漏、Apache 多進程模型不匹配。生產環境建議短連接+連接池。
這 21 條實踐覆蓋查詢、索引、結構、引擎、連接、安全全鏈路。核心心法:理解底層機制(B+Tree、鎖、緩存、協議),在應用層做正確選擇。定期 EXPLAIN 慢查詢,持續優化,而非一次性調優。