2011-06-29 29 views
13

Tôi đang chạy một truy vấn như thế này trong MSSQL2008:Có phải "SELECT COUNT (cột)" nhanh hơn/chậm hơn "SELECT COUNT (*)" không?

select count(*) 
from t1 
inner join t2 on t1.id = t2.t1_id 
inner join t3 on t1.id = t3.t1_id 

Giả t1.id có một hạn chế NOT NULL. Vì chúng là các kết nối bên trong và t1.id không bao giờ có thể rỗng, sử dụng count(t1.id) thay vì count(*) nên tạo kết quả cuối cùng giống hệt nhau. Câu hỏi của tôi là: Liệu hiệu suất có giống nhau không?

Tôi cũng tự hỏi liệu các kết nối có thể ảnh hưởng đến điều này hay không. Tôi nhận thấy rằng việc thêm hoặc xóa một kết nối sẽ ảnh hưởng đến cả hiệu suất và độ dài của tập kết quả. Giả sử rằng không thay đổi mẫu kết nối, bạn đặt count để chỉ nhắm mục tiêu một bảng. Nó có tạo nên sự khác biệt nào không? Nói cách khác, có một sự khác biệt giữa hai truy vấn sau đây:

select count(*) from t1 inner join t2 on t1.id = t2.t1_id 
select count(t1.*) from t1 inner join t2 on t1.id = t2.t1_id 

COUNT(id) vs. COUNT(*) in MySQL câu trả lời câu hỏi này cho MySQL, nhưng tôi không thể tìm thấy câu trả lời cho MS-SQL đặc biệt, và tôi không thể tìm thấy bất cứ điều gì ở tất cả những gì lấy yếu tố join.

LƯU Ý: Tôi đã cố gắng tìm thông tin này trên cả Google và SO, nhưng thật khó để tìm ra cách từ tìm kiếm của tôi.

+0

Bản sao có thể xảy ra: http://stackoverflow.com/questions/1221559/count-vs-count1 http://stackoverflow.com/questions/2710621/count -vs-count1-vs-countpk-which-is-better –

Trả lời

-1

select count(*) sẽ chậm hơn khi cố gắng tìm nạp mọi thứ. Chỉ định một cột (PK hoặc bất kỳ cột được lập chỉ mục nào khác) sẽ tăng tốc độ mọi thứ khi công cụ truy vấn biết trước thời gian mà nó đang tìm kiếm. Nó cũng sẽ sử dụng một chỉ số trái với việc đi ngược lại bảng.

+0

Tôi nghĩ rằng điều này đã đúng một thời gian dài trước đây, nhưng các cuộc thảo luận trước đây về chủ đề này cho thấy rằng điều này không còn là trường hợp. Cơ sở dữ liệu đủ thông minh để biết rằng số (*) chỉ nên kiểm tra sự tồn tại của một hàng và sẽ không tìm nạp tất cả các giá trị cho hàng. http://stackoverflow.com/questions/1221559/count-vs-count1 –

+0

@Micheal: Tôi không nghĩ điều này là phổ biến. Ví dụ, lần cuối cùng tôi kiểm tra, DB2 trên zOS v9 vẫn tìm nạp mọi thứ. Đã khá lâu rồi. Trừ khi người ta biết chính xác công việc của DB mà anh ta đang xử lý, tôi đoán nó an toàn để tránh đếm (*). – Mrchief

+0

Ok, tôi đã sửa chữa - điều đó nghe có vẻ hợp lý rằng nó không phổ biến đúng ... nhưng OP đã chỉ định SQL Server 2008. –

8

Tôi đã thử một số SELECT COUNT(*) FROM MyTable so với SELECT COUNT(SomeColumn) FROM MyTable với các kích thước khác nhau của bảng và vị trí SomeColumn một lần là cột khóa nhóm, một khi nó nằm trong chỉ mục không được nhóm và sau khi không có chỉ mục.

Trong mọi trường hợp, với mọi quy mô của bảng (từ 300'000 hàng đến 170 triệu hàng), tôi không bao giờ nhìn thấy bất kỳ sự khác biệt về một trong hai kế hoạch tốc độ cũng không thực hiện - trong mọi trường hợp, các COUNT được xử lý bởi thực hiện quét chỉ mục nhóm -> tức là quét toàn bộ bảng, về cơ bản. Nếu có một chỉ mục không nhóm lại, thì quá trình quét nằm trên chỉ mục đó - ngay cả khi thực hiện một SELECT COUNT(*)!

Có vẻ như không có bất kỳ sự khác biệt nào về tốc độ hoặc cách tiếp cận những thứ đó - để tính tất cả, SQL Server chỉ cần quét toàn bộ bảng - thời gian.

thử nghiệm đã được thực hiện trên SQL Server 2008 R2 Developer Edition

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