เมื่อต้องการแสดงจำนวนแถวทั้งหมด (Total Row Count) พร้อมกับข้อมูลแต่ละแถว วิธีที่มีประสิทธิภาพคือใช้ Subquery ด้วย COUNT(*) ซึ่ง MySQL จะคำนวณครั้งเดียวแล้ว Broadcast ไปทุกแถว
สร้างตารางและข้อมูล 10 แถว
mysql> create table DemoTable (
StudentId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
StudentFirstName varchar(20),
StudentAge int
);
mysql> insert into DemoTable(StudentFirstName,StudentAge) values
('John',23),('Larry',21),('Johnny',23),('Chris',21),('David',23),
('James',21),('Jace',24),('Mike',21),('Robert',25),('Mike',22);
คำสั่งนับแถวรวมพร้อมแสดงข้อมูล
mysql> select StudentFirstName,
(select count(*) from DemoTable) AS Total_Count
from DemoTable limit 10;
ผลลัพธ์
+------------------+-------------+ | StudentFirstName | Total_Count | +------------------+-------------+ | John | 10 | | Larry | 10 | | Johnny | 10 | | Chris | 10 | | David | 10 | | James | 10 | | Jace | 10 | | Mike | 10 | | Robert | 10 | | Mike | 10 | +------------------+-------------+
ทำไมวิธีนี้เร็วที่สุด?
- Subquery Scalar - MySQL Optimizer รู้ว่าค่าคงที่ คำนวณครั้งเดียว
- ไม่ต้อง Join หรือ Window Function
- ใช้ Index ได้เต็มที่สำหรับ COUNT(*) บน Primary Key
วิธีอื่นและเปรียบเทียบ
| วิธี | คำสั่ง | ประสิทธิภาพ | หมายเหตุ |
|---|---|---|---|
| Subquery (แนะนำ) | (SELECT COUNT(*) FROM t) | ⭐⭐⭐ เร็วที่สุด | คำนวณครั้งเดียว |
| Window Function (8.0+) | COUNT(*) OVER() | ⭐⭐ เร็ว | ทันสมัย อ่านง่าย |
| CROSS JOIN | CROSS JOIN (SELECT COUNT(*) c FROM t) x | ⭐⭐ เร็ว | รูปแบบเก่า |
| Variable | @cnt := (SELECT COUNT(*) FROM t) | ⭐ ช้ากว่า | ไม่แนะนำ |
| Application Count | SELECT COUNT(*) แยก | ⭐ ช้า | 2 Round-trips |
ข้อควรระวัง
- COUNT(*) นับทุกแถว รวม NULL ด้วย
- COUNT(column) นับเฉพาะค่าที่ไม่ NULL
- บน InnoDB COUNT(*) เร็วมากเพราะมี metadata
- หากมี WHERE ให้ใส่ใน Subquery ด้วย:
(SELECT COUNT(*) FROM DemoTable WHERE age > 20)