「表有多少行?下一個自增 ID 是多少?最大 ID 是多少?」這三個問題看似簡單,但不同存儲引擎、不同業務場景下的最優解截然不同。本文系統總結 5 種方法,並給出性能對比與選型建議。
-- 標準方法:適用所有引擎,走主鍵索引,極快 SELECT MAX(`id`) FROM `your_table`;
⚠️ 若 `id` 非主鍵/無索引,將全表掃描,需加索引。
自增值屬於表元數據,存儲在信息架構中。
SELECT `AUTO_INCREMENT` FROM `INFORMATION_SCHEMA`.`TABLES` WHERE `TABLE_SCHEMA` = 'your_db' AND `TABLE_NAME` = 'your_table';
$stmt = $pdo->query("SHOW TABLE STATUS LIKE 'your_table'");
$row = $stmt->fetch(PDO::FETCH_ASSOC);
echo $row['Auto_increment'];
SELECT COUNT(`id`) FROM `your_table`;
SELECT SQL_CALC_FOUND_ROWS * FROM `your_table` LIMIT 20; SELECT FOUND_ROWS(); -- 返回不帶 LIMIT 的總行數
方法 引擎 精確度 千萬行耗時 適用場景 MAX(id) 所有 精確 < 1ms 獲取業務最大主鍵 SHOW TABLE STATUS 所有 自增值精確,行數估算 < 1ms 獲取自增值、表元數據 COUNT(*) InnoDB 精確 0.5-5 秒 業務需精確總數、低頻查詢 COUNT(*) MyISAM 精確 < 1ms MyISAM 表精確計數 TABLE_ROWS InnoDB 估算(誤差 ±10%+) < 1ms 大表近似行數、監控大屏 觸發器計數表 所有 精確 < 1ms 極高寫入、高頻計數讀取 五、 選型決策樹
- 需 **精確總數** 且 **低頻** → `COUNT(*)`(InnoDB 可接受秒級)
- 需 **精確總數** 且 **高頻/大表** → 觸發器維護計數表
- 需 **近似總數** 且 **極快** → `TABLE_ROWS` / `SHOW TABLE STATUS`
- 需 **下一個自增 ID** → `SHOW TABLE STATUS` 或 `INFORMATION_SCHEMA`
- 需 **業務最大 ID** → `MAX(id)`(確保有主鍵索引)
MySQL 統計信息獲取沒有銀彈,關鍵在於業務對精確度的容忍度與查詢頻率的權衡。將本文 5 類方法納入團隊知識庫,根據具體場景按決策樹選型,即可避免「大表 COUNT(*) 卡死業務」或「緩存行數不準導致分頁錯誤」等經典生產事故。