統計資料表行數是最基礎也最常見的操作,但不同寫法在性能、語義上卻有細微差別。本文梳理三種主流做法及適用場景。
SELECT COUNT(*) FROM tableName; -- 或 SELECT COUNT(1) FROM tableName;
* 與 1 在優化器層面等價,無性能差異。WHERE 縮小範圍。SELECT COUNT(id) FROM tableName;
id 列非 NULL的行數。COUNT(*);若列有索引,優化器可能選擇掃描該索引(比聚簇索引窄),速度更快。SELECT TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'table_name';
TABLE_ROWS 為估算值(誤差可達 40%~50%),MyISAM 則精確。| 方法 | 精確度 | 速度 | 推薦場景 |
|---|---|---|---|
| COUNT(*) / COUNT(1) | 精確 | 大表較慢(全掃描) | 業務精確統計、小中型表 |
| COUNT(indexed_col) | 精確(非NULL) | 較快(掃描次級索引) | 大表且有合適索引 |
| information_schema.TABLE_ROWS | 估算(InnoDB) | 極快 | 大表估算、監控、非關鍵業務 |
若業務極度依賴實時精確行數且表極大,可建立計數表 + 觸發器維護:
CREATE TABLE table_counts (table_name VARCHAR(64) PRIMARY KEY, row_count BIGINT); -- INSERT/DELETE 觸發器更新 row_count
讀取時直接 SELECT row_count FROM table_counts WHERE table_name='...',O(1) 精確返回。
精確用 COUNT(*),估算用 information_schema,大表有索引可用 COUNT(index_col)。理解底層機制,才能在正確性與性能間做最佳取捨。