Thilo đã đóng đinh sự khác biệt một cách chính xác ... COUNT( column_name )
có thể trả về một số thấp hơn COUNT( * )
if column_name
có thể là NULL
.
Tuy nhiên, nếu tôi có thể có một góc độ khác khi trả lời câu hỏi của bạn, vì bạn dường như đang tập trung vào hiệu suất.
Trước tiên, hãy lưu ý rằng việc phát hành bảng SELECT COUNT(*) FROM table;
sẽ có khả năng chặn người viết và nó cũng sẽ bị người đọc / người viết khác chặn trừ khi bạn đã thay đổi mức cô lập (đầu gối có xu hướng WITH (NOLOCK)
nhưng tôi thấy một số người đầy hứa hẹn cuối cùng cũng bắt đầu tin vào RCSI). Điều đó có nghĩa là trong khi bạn đang đọc dữ liệu để có được số lượng "chính xác" của mình, tất cả các yêu cầu DML này đang chồng chất lên nhau và khi cuối cùng bạn đã giải phóng tất cả các ổ khóa của mình, các ổ khóa sẽ mở ra, một loạt các chèn / cập nhật / xóa hoạt động xảy ra và sẽ có số lượng "chính xác" của bạn.
Nếu bạn cần số lượng hàng hoàn toàn nhất quán và chính xác về giao dịch (ngay cả khi nó chỉ có giá trị trong số mili giây cần để trả lại số cho bạn), thì hãy SELECT COUNT( * )
là sự lựa chọn duy nhất của bạn.
Mặt khác, nếu bạn đang cố gắng lấy bóng chính xác 99,9%, bạn nên sử dụng một truy vấn như sau:
SELECT row_count = SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE [object_id] = OBJECT_ID('dbo.Table')
AND index_id IN (0,1);
(SUM
có để tính đến các bảng được phân vùng - nếu bạn không sử dụng tính năng phân vùng bảng, bạn có thể bỏ nó đi.)
DMV này duy trì số lượng hàng chính xác cho các bảng ngoại trừ các hàng hiện đang tham gia vào các giao dịch - và chính những giao dịch đó là những giao dịch sẽ tạo nên SELECT COUNT
của bạn đợi truy vấn (và cuối cùng làm cho nó không chính xác trước khi bạn có thời gian để đọc nó). Nhưng nếu không, điều này sẽ dẫn đến câu trả lời nhanh hơn nhiều so với truy vấn bạn đề xuất và không kém chính xác hơn so với việc sử dụng WITH (NOLOCK)
.