Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Phương pháp nhanh nhất để lấy tổng số hàng cho truy vấn MySQL?

Để lấy tổng số hàng của một truy vấn và hiển thị cùng với từng hàng kết quả, sử dụng truy vấn con (subquery) với COUNT(*).

Tạo bảng sinh viên

mysql> CREATE TABLE DemoTable (
    -> StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> StudentFirstName VARCHAR(20),
    -> StudentAge INT
    -> );

Chèn 10 bản ghi mẫu

mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('John', 23);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Larry', 21);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Johnny', 23);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Chris', 21);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('David', 23);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('James', 21);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Jace', 24);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Mike', 21);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Robert', 25);
mysql> INSERT INTO DemoTable(StudentFirstName, StudentAge) VALUES('Mike', 22);

Truy vấn lấy tổng số hàng cho mỗi bản ghi

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          |
+------------------+-------------+

Phân tích hiệu năng

  • Ưu điểm: Đơn giản, dễ hiểu, tổng số hàng được tính một lần cho toàn bộ truy vấn
  • Nhược điểm: Subquery thực thi cho mỗi hàng (tùy optimizer), có thể chậm trên bảng lớn

Các phương án thay thế hiệu quả hơn

1. Biến người dùng (User-defined variable)

SELECT @total := COUNT(*) FROM DemoTable;
SELECT StudentFirstName, @total AS Total_Count FROM DemoTable;

2. CTE (MySQL 8.0+)

WITH Total AS (SELECT COUNT(*) AS cnt FROM DemoTable)
SELECT StudentFirstName, Total.cnt AS Total_Count FROM DemoTable, Total;

3. SQL_CALC_FOUND_ROWS (đã deprecated MySQL 8.0.17+)

SELECT SQL_CALC_FOUND_ROWS StudentFirstName FROM DemoTable LIMIT 10;
SELECT FOUND_ROWS();

Khuyến nghị

Với bảng lớn, hãy dùng CTE hoặc biến người dùng. Tránh SQL_CALC_FOUND_ROWS vì đã bị loại bỏ.