0
0
Lập trình
Admin Team
Admin Teamtechmely

So sánh hiệu suất giữa Count(*) và Count(1): Lựa chọn nào là tốt hơn?

Đăng vào 3 ngày trước

• 4 phút đọc

Chào các bạn!

Trong việc quản lý dữ liệu, chúng ta thường xuyên phải đếm số lượng bản ghi trong các bảng. Một trong những hàm hữu ích nhất trong SQL chính là COUNT, nhưng ít ai thực sự hiểu rõ sự khác biệt giữa các tham số khác nhau mà hàm này có thể nhận, chẳng hạn như COUNT(*), COUNT(1)COUNT(column).

Nội dung bài viết

Bài viết này sẽ giúp bạn hiểu rõ hơn về hiệu suất của từng loại câu lệnh đếm. Chúng ta sẽ khám phá:

  • Câu lệnh đếm nào có hiệu suất tốt nhất
  • Các yếu tố ảnh hưởng đến hiệu suất khi sử dụng hàm COUNT
  • Cách tối ưu cho việc đếm bản ghi trong các bảng lớn

1. Hiệu suất của các câu lệnh COUNT

Trước tiên, chúng ta hãy đi đến kết luận chung về hiệu suất của các loại câu lệnh đếm:

Copy
COUNT(*) = COUNT(1) > COUNT(primary key column) > COUNT(column)

1.1. COUNT() là gì?

Hàm COUNT(arg) là một hàm tổng hợp dùng để đếm số lượng bản ghi thỏa mãn điều kiện nhất định. Tham số arg có thể là một cột, hằng số hoặc đơn giản là ký tự *. Câu lệnh COUNT(column) sẽ đếm số lượng bản ghi có giá trị không phải NULL trong cột đó.

Ví dụ:

Copy
SELECT COUNT(name) FROM member;

Lệnh này sẽ đếm số lượng bản ghi trong bảng member mà trường name không phải là NULL.

1.2. So sánh COUNT(primary key column) và COUNT(1)

Khi đếm số lượng bản ghi thông qua COUNT(arg), MySQL sẽ tạo ra một biến count và duyệt qua tất cả các bản ghi. Nếu giá trị của arg khác NULL, biến count sẽ được tăng lên. Đặc biệt, khi sử dụng COUNT(1), MySQL sẽ không cần phải đọc giá trị của trường, do đó điều này giúp tiết kiệm thời gian tính toán:

Copy
SELECT COUNT(1) FROM member;

Khi chỉ có clustered index mà không có secondary index, InnoDB sẽ duyệt qua clustered index mà không cần đọc giá trị khóa chính, từ đó tăng tốc độ thực thi.

1.3. COUNT(*) hoạt động như thế nào?

Nhiều người nhầm lẫn rằng COUNT(*) sẽ đọc tất cả các giá trị của trường trong bảng. Trên thực tế, MySQL chuyển đổi COUNT(*) thành COUNT(0) khi thực thi. Vì vậy, tốc độ thực thi của cả COUNT(*)COUNT(1) là như nhau, không có sự khác biệt về hiệu suất.

1.4. Hiệu suất của COUNT(column)

Ví dụ:

Copy
SELECT COUNT(name) FROM member;

Với câu lệnh này, MySQL cần duyệt toàn bộ bảng để đếm, cho nên hiệu suất sẽ kém hơn so với COUNT(1)COUNT(*). Tuy nhiên, nếu trường column có secondary index, hiệu suất có thể được cải thiện đáng kể.

2. COUNT trong các tình huống khác

2.1. Các Storage Engine khác nhau

Mỗi storage engine có cơ chế hoạt động riêng và điều này cũng ảnh hưởng đến cách thức hàm COUNT được thực thi. Ví dụ, trong MyISAM, có metadata chứa giá trị row_count, cho phép đếm nhanh chóng mà không cần phải scan toàn bộ bảng. Đối với InnoDB, mọi thứ thường phức tạp hơn.

2.2. COUNT khi có transaction

Với InnoDB, trong các tình huống có nhiều transaction, giá trị COUNT có thể khác nhau tùy thuộc vào mức độ cách ly của transaction. Điều này có thể dẫn đến sự không nhất quán trong kết quả đếm khi cùng một lúc hai session thực hiện truy vấn.

3. Tối ưu hóa COUNT(*) cho bảng lớn

Khi làm việc với các bảng lớn có hàng triệu bản ghi, thời gian thực thi cho COUNT(*) có thể rất lâu. Dưới đây là một số phương pháp tối ưu:

3.1. Ước lượng giá trị

Nếu không cần độ chính xác tuyệt đối, bạn có thể sử dụng lệnh EXPLAIN để ước lượng số lượng bản ghi mà không cần quét bảng thực tế.

3.2. Tạo bảng đếm riêng

Một cách khác là tạo một bảng riêng để lưu trữ giá trị đếm. Khi thêm hoặc xóa bản ghi trong bảng chính, bạn có thể cập nhật giá trị trong bảng đếm.

Kết luận

Như vậy, để đạt hiệu suất tốt nhất khi đếm bản ghi trong MySQL, bạn nên:

  • Sử dụng COUNT(*) hoặc COUNT(1) cho hiệu năng tốt nhất.
  • Tránh sử dụng COUNT(column) với các trường không có index vì hiệu suất kém.
  • Tận dụng secondary index nếu có thể để cải thiện tốc độ truy vấn.

Hy vọng bài viết này giúp ích cho bạn trong việc hiểu rõ hơn về hàm COUNT và cách tối ưu hóa việc đếm trong MySQL. Hẹn gặp lại trong những bài viết tiếp theo!

Nếu bạn thấy bài viết hữu ích, hãy cho mình một lượt upvote 🔼 và chia sẻ nhé!
Cảm ơn các bạn rất nhiều!
🧑‍💻 70+ Ronin Engineers: https://ronin-engineer.github.io/c1/
📚️ System Design VN: https://fb.com/groups/systemdesign.vn
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào