2010-02-08 54 views
17

Tôi sử dụng hàm SQL COUNT để lấy tổng số hoặc hàng từ một bảng. Có sự khác biệt nào giữa hai câu sau không?Đếm (*) so với Đếm (Id) trong máy chủ sql 2005

SELECT COUNT(*) FROM Table 

SELECT COUNT(TableId) FROM Table 

Ngoài ra, là có bất kỳ sự khác biệt về hiệu suất và thời gian thực hiện?

+0

Đã trả lời nhưng thảo luận khá tốt về vấn đề này tại đây: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/31795984-ea62-4b2c-8c78-6e986f2bcea0 –

Trả lời

18

Thilo đóng đinh chính xác sự khác biệt ... COUNT(column_name) có thể trả lại số thấp hơn COUNT(*) nếu column_name có thể là NULL.

Tuy nhiên, nếu tôi có thể có một góc hơi khác khi trả lời câu hỏi của bạn, vì dường như bạn đang tập trung vào hiệu suất.

Trước tiên, lưu ý rằng việc phát hành SELECT COUNT(*) FROM table; có khả năng sẽ chặn nhà văn và cũng sẽ bị chặn bởi người đọc/nhà văn khác trừ khi bạn đã thay đổi cấp độ cách ly (đầu gối có xu hướng là WITH (NOLOCK) nhưng tôi thấy một số hứa hẹn cuối cùng mọi người bắt đầu tin vào RCSI). Điều đó có nghĩa là khi bạn đọc dữ liệu để có được số lượng "chính xác", tất cả các yêu cầu DML này sẽ được xếp chồng lên nhau và cuối cùng bạn đã giải phóng tất cả các khóa của mình, lũ lụt mở ra, một loạt chèn/cập nhật/xóa hoạt động xảy ra và có số lượng "chính xác" của bạn.

Nếu bạn cần số hàng chính xác nhất quán và chính xác (ngay cả khi nó chỉ hợp lệ cho số mili giây để trả lại số cho bạn), thì SELECT COUNT(*) là lựa chọn duy nhất của bạn.

Mặt khác, nếu bạn đang cố gắng để có được một sân chơi bóng chày chính xác 99,9%, bạn sẽ được tốt hơn off với một truy vấn như thế này:

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); 

(Các SUM là có để giải thích cho các bảng phân vùng - nếu bạn không sử dụng phân vùng bảng, bạn có thể bỏ phân vùng bảng.)

DMV này duy trì số hàng chính xác cho các bảng ngoại trừ các hàng hiện đang tham gia giao dịch - và những giao dịch đó là giao dịch thực hiện yêu cầu SELECT COUNT truy vấn của bạ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 khi sử dụng WITH (NOLOCK).

+0

Sẽ đếm (Primary_Key) sẽ là một lựa chọn tốt hơn so với truy vấn ở trên? Nó luôn luôn nên cung cấp một số chính xác vì không thể có một khóa chính với giá trị null. –

+2

COUNT (PK) và COUNT (*) sẽ giống hệt nhau trong trường hợp đó. Mỗi cái sẽ cho một số đếm chính xác, nhưng vẫn có thể là một kẻ chặn và vẫn có thể bị chặn. Vì vậy, cho dù kẻ giết người hiệu suất tiềm năng có giá trị độ chính xác là tùy thuộc vào bạn (hãy nhớ rằng nếu bạn "giải quyết" vấn đề bằng cách sử dụng NOLOCK, bạn đã mất đi độ chính xác của bạn anyway). –

+0

Tôi luôn luôn nghĩ rằng Count (PK) hoạt động tốt hơn Count (*). Cảm ơn bạn đã xóa thông tin này. –

12

số (id) cần phải kiểm tra cột (có thể được tối ưu hóa cho khóa chính hoặc cột không trống), vì vậy hãy tính (*) hoặc đếm (1) (trừ khi bạn thực sự muốn biết số hàng có giá trị không null cho id).

Các vấn đề liên quan