Apa perbedaan antara jumlah pilih (*) dan jumlah pilih (any_non_null_column)?

58

Saya ingat bahwa (pada Oracle) ada perbedaan antara mengucapkan select count(*) from any_tabledan select count(any_non_null_column) from any_table.

Apa perbedaan antara kedua pernyataan ini, jika ada?

Martin
sumber

Jawaban:

72
  • COUNT (*) akan termasuk NULLS
  • COUNT (column_or_expression) tidak akan.

Ini berarti COUNT(any_non_null_column)akan memberikan yang sama seperti COUNT(*)tentu saja karena tidak ada nilai NULL yang menyebabkan perbedaan.

Secara umum, COUNT(*)harus lebih baik karena indeks apa pun dapat digunakan karena COUNT(column_or_expression)mungkin tidak diindeks atau SARGable

Dari ANSI-92 (cari " Scalar expressions 125")

Kasus:

a) Jika COUNT (*) ditentukan, maka hasilnya adalah kardinalitas T.

b) Kalau tidak, biarkan TX menjadi tabel kolom tunggal yang merupakan hasil dari penerapan <ekspresi nilai> untuk setiap baris T dan menghilangkan nilai nol. Jika satu atau lebih nilai nol dihilangkan, maka kondisi penyelesaian dinaikkan: peringatan - nilai nol dihilangkan dalam fungsi yang ditetapkan.

Aturan yang sama berlaku untuk SQL Server dan Sybase terlalu setidaknya

Catatan: COUNT (1) sama dengan COUNT (*) karena 1 adalah ekspresi yang tidak dapat dibatalkan.

gbn
sumber
4
Hanya untuk kelengkapan: Oracle akan menggunakan pemindaian indeks pada kolom tidak-diindeks yang diindeks jika count(*)digunakan.
a_horse_with_no_name
Saya pikir tiga opsi yang mungkin adalah COUNT(*), COUNT(<constant>)dan COUNT(<column name>)dan ketiganya bisa diawali dengan ALLatau DISTINCT(standarnya ALLjika dihilangkan). Saya hanya ingin tahu ekspresi apa yang dapat digunakan di mana Anda katakan _or_expression?
onedaywhen
2
@onedayKetika COUNT(1)sebagai contoh tidak berguna, itu sama dengan COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)sebagai contoh yang menghitung baris di mana a> b.
ypercubeᵀᴹ
16

Dalam setiap versi Oracle terbaru (yaitu 8.x + ) mereka melakukan hal yang sama . Dengan kata lain satu-satunya perbedaan adalah semantik:

select count(*) from any_table

mudah dibaca dan jelas apa yang Anda coba lakukan, dan

select count(any_non_null_column) from any_table

lebih sulit dibaca karena

  1. lebih panjang
  2. itu kurang dikenali
  3. Anda harus memikirkan apakah any_non_null_columnbenar-benar diberlakukan sebagainot null

Singkatnya, gunakancount(*)

Jack Douglas
sumber
1

Dalam buku Panduan Ujian Sertifikasi DBA Profesional Bersertifikat Oracle8i (ISBN 0072130601) , halaman 78 mengatakan COUNT (1) akan benar-benar berjalan lebih cepat daripada COUNT (*) karena mekanisme tertentu dipanggil untuk memeriksa kamus data untuk ketidakmampuan setiap kolom (atau setidaknya kolom pertama yang tidak dapat dibatalkan) saat menggunakan COUNT (*) . COUNT (1) melewati mekanisme tersebut.

Curang MySQL untuk 'SELECT COUNT (1) di tblname;' pada tabel MyISAM dengan membaca header tabel untuk jumlah tabel. InnoDB dihitung setiap saat.

Untuk menguji apakah COUNT (1) akan berjalan lebih cepat dari COUNT (*) dalam cara agnostik basis data, jalankan saja yang berikut dan tentukan waktu berjalannya sendiri:

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

Ini membuat fungsi COUNT beroperasi pada bidang bermain level yang sama terlepas dari mesin penyimpanan atau RDBMS.

RolandoMySQLDBA
sumber
8
Panduan ujian salah. Dalam hitungan Oracle (*) = jumlah (1) (setidaknya setelah versi 7). Lihat asktom.oracle.com/pls/asktom/… (Sudah direferensikan oleh @JackPDouglas)
Leigh Riffel
3
Menarik. COUNT (*) seharusnya tidak memeriksa kolom sama sekali sesuai spesifikasi ANSI. Diminta pada SO untuk SQL Server beberapa waktu lalu juga stackoverflow.com/questions/1221559/count-vs-count1/…
gbn
@ gbn, @Leigh Riffel, @bernd_k Terima kasih telah menimpali dan mengingatkan saya untuk membaca dan belajar lebih banyak, terutama karena saya belum lama bekerja dengan Oracle.
RolandoMySQLDBA