Sự khác biệt giữa số đếm chọn (*) và số đếm chọn (any_non_null_column) là gì?


58

Tôi dường như nhớ rằng (trên Oracle) có một sự khác biệt giữa cách nói select count(*) from any_tableselect count(any_non_null_column) from any_table.

Sự khác biệt giữa hai tuyên bố này, nếu có là gì?

Câu trả lời:


72
  • COUNT (*) sẽ bao gồm NULLS
  • COUNT (cột_or_expression) sẽ không.

Điều này có nghĩa là COUNT(any_non_null_column)sẽ cung cấp giống như COUNT(*)tất nhiên vì không có giá trị NULL để gây ra sự khác biệt.

Nói chung, COUNT(*)nên tốt hơn bởi vì bất kỳ chỉ mục nào cũng có thể được sử dụng vì COUNT(column_or_expression)có thể không được lập chỉ mục hoặc SARGable

Từ ANSI-92 (tìm " Scalar expressions 125")

Trường hợp:

a) Nếu COUNT (*) được chỉ định, thì kết quả là giá trị chính của T.

b) Mặt khác, đặt TX là bảng một cột là kết quả của việc áp dụng <biểu thức giá trị> cho mỗi hàng của T và loại bỏ các giá trị null. Nếu một hoặc nhiều giá trị null bị loại bỏ, thì một điều kiện hoàn thành sẽ được đưa ra: cảnh báo- giá trị null được loại bỏ trong hàm set.

Các quy tắc tương tự áp dụng cho SQL Server và Sybase quá ít nhất

Lưu ý: COUNT (1) giống với COUNT (*) vì 1 là biểu thức không thể rỗng.


4
Chỉ để hoàn thiện: Oracle sẽ sử dụng quét chỉ mục trên cột không được lập chỉ mục nếu count(*)được sử dụng.
a_horse_with_no_name

Tôi nghĩ rằng ba tùy chọn có thể là COUNT(*), COUNT(<constant>)COUNT(<column name>)cả ba đều có thể được thêm tiền tố vào ALLhoặc DISTINCT(mặc định là ALLnếu bị bỏ qua). Tôi chỉ tự hỏi những biểu hiện có thể được sử dụng ở nơi bạn nói _or_expression?
ngày

2
@encedaywhen COUNT(1)là một ví dụ vô dụng, nó giống như COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)như một ví dụ đếm các hàng trong đó a> b.
ypercubeᵀᴹ

16

Trong bất kỳ phiên bản gần đây (tức là 8.x + ) của Oracle, họ đều làm điều tương tự . Nói cách khác, sự khác biệt duy nhất là ngữ nghĩa:

select count(*) from any_table

dễ đọc và rõ ràng những gì bạn đang cố gắng làm, và

select count(any_non_null_column) from any_table

khó đọc hơn vì

  1. nó dài hơn
  2. nó ít được nhận ra
  3. bạn phải suy nghĩ về việc any_non_null_columnthực sự được thi hành nhưnot null

Tóm lại, sử dụngcount(*)


9

Trong một phiên bản gần đây, thực sự không có sự khác biệt giữa số đếm (*) và số đếm ( bất kỳ cột nào không null ), với phần nhấn mạnh là không null :-) Đã tình cờ đề cập đến chủ đề đó bằng một bài đăng trên blog: Số đếm (col) tốt hơn số đếm (*)?


1

Trong cuốn sách Hướng dẫn kiểm tra chứng chỉ DBA chuyên nghiệp được chứng nhận Oracle8i (ISBN 0072130601) , trang 78 cho biết COUNT (1) sẽ thực sự chạy nhanh hơn COUNT (*) vì các cơ chế nhất định được gọi để kiểm tra từ điển dữ liệu cho tính vô hiệu của mỗi cột (hoặc ít nhất là cột đầu tiên không có giá trị) khi sử dụng COUNT (*) . COUNT (1) bỏ qua các cơ chế đó.

MySQL gian lận cho 'CHỌN COUNT (1) trên tblname;' trên các bảng MyISAM bằng cách đọc tiêu đề bảng cho số lượng bảng. InnoDB đếm mỗi lần.

Để kiểm tra xem COUNT (1) có chạy nhanh hơn COUNT (*) theo cách không xác định cơ sở dữ liệu hay không, chỉ cần chạy như sau và tự đánh giá thời gian chạy:

SELECT COUNT(1) FROM tblname WHERE 1 = 1;
SELECT COUNT(*) FROM tblname WHERE 1 = 1;
SELECT COUNT(column-name) FROM tblname WHERE 1 = 1;

Điều này làm cho hàm COUNT hoạt động trên cùng một sân chơi cấp độ bất kể công cụ lưu trữ hoặc RDBMS.


8
Hướng dẫn thi sai. Trong Oracle đếm (*) = đếm (1) (ít nhất là sau phiên bản 7). Xem Asktom.oracle.com/pls/asktom/ khăn (Đã được tham khảo bởi @JackPDoureb)
Leigh Riffel

3
Hấp dẫn. COUNT (*) hoàn toàn không nên kiểm tra các cột theo thông số ANSI. Đã được hỏi trên SO cho SQL Server một thời gian trước đây quá stackoverflow.com/questions/1221559/count-vs-count1/
gợi

@gbn, @Leigh Riffel, @bernd_k Cảm ơn bạn đã ghé thăm và nhắc nhở tôi đọc và tìm hiểu thêm, đặc biệt là vì tôi đã không làm việc với Oracle trong một thời gian.
RolandoMySQLDBA
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.