การนับแถวด้วย COUNT(*) ในตารางใหญ่อาจช้า เพราะต้อง Scan ทั้งตาราง (Full Table Scan) มีวิธีที่เร็วกว่าสำหรับกรณีเฉพาะ
วิธีที่ 1: COUNT(*) - มาตรฐานและแม่นยำที่สุด
SELECT COUNT(*) FROM RowCountDemo;
- ✅ แม่นยำ 100% (นับทุกแถว รวม Deleted/Uncommitted ใน MVCC)
- ✅ ใช้ Index ได้ (ถ้ามี Index) - MySQL จะเลือก Index ที่เล็กที่สุด
- ⚠️ ช้าในตารางใหญ่ (Millions of rows)
วิธีที่ 2: ใช้ INFORMATION_SCHEMA (เร็วมาก แต่มั่นใจไม่ได้ 100%)
SELECT TABLE_ROWS
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'database_name'
AND TABLE_NAME = 'table_name';
- ⚡ เร็วมาก (อ่าน Metadata เลย ไม่ Scan Table)
- ⚠️ ประมาณการ (Approximate) สำหรับ InnoDB
- ⚠️ ไม่นับ Uncommitted Transactions
- ✅ แม่นยำสำหรับ MyISAM
วิธีที่ 3: ใช้ Trigger + Counter Table (แม่นยำ + เร็ว)
-- สร้างตารับนับ
CREATE TABLE table_stats (
table_name VARCHAR(64) PRIMARY KEY,
row_count BIGINT DEFAULT 0
);
-- Trigger AFTER INSERT
CREATE TRIGGER after_insert_demo
AFTER INSERT ON RowCountDemo
FOR EACH ROW
UPDATE table_stats SET row_count = row_count + 1 WHERE table_name = 'RowCountDemo';
-- Trigger AFTER DELETE
CREATE TRIGGER after_delete_demo
AFTER DELETE ON RowCountDemo
FOR EACH ROW
UPDATE table_stats SET row_count = row_count - 1 WHERE table_name = 'RowCountDemo';
-- Query เร็วมาก
SELECT row_count FROM table_stats WHERE table_name = 'RowCountDemo';
วิธีที่ 4: FOUND_ROWS() (หลัง SELECT SQL_CALC_FOUND_ROWS)
SELECT SQL_CALC_FOUND_ROWS * FROM RowCountDemo LIMIT 10;
SELECT FOUND_ROWS();
⚠️ Deprecated ใน MySQL 8.0.17+
ตารางเปรียบเทียบ
| วิธี | ความเร็ว | ความแม่นยำ | ใช้ได้กับ Engine |
|---|---|---|---|
| COUNT(*) | ช้า (Full Scan) | 100% | ทั้งหมด |
| TABLE_ROWS | เร็วที่สุด | ประมาณ (InnoDB) | InnoDB (ประมาณ), MyISAM (แม่นยำ) |
| Trigger + Counter | เร็วที่สุด (Read) | 100% | ทั้งหมด |
| FOUND_ROWS() | ปานกลาง | 100% | ทั้งหมด (Deprecated) |
แนะนำ
- ต้องการแม่นยำ 100%:
COUNT(*)(มี Index ให้เร็วขึ้น) - Dashboard/Stats ไม่ต้องแม่นยำ:
TABLE_ROWS - Real-time Counter: Trigger + Counter Table
- เพิ่ม Index บนคอลัมน์ที่ Filter บ่อย เพื่อ COUNT เร็วขึ้น