Jaka jest różnica między select count (*) a select count (any_non_null_column)?


58

Wydaje mi się, że pamiętam, że (w Oracle) istnieje różnica między wypowiadaniem select count(*) from any_tablea select count(any_non_null_column) from any_table.

Jakie są różnice między tymi dwoma stwierdzeniami, jeśli takie istnieją?

Odpowiedzi:


72
  • COUNT (*) będzie zawierać NULLS
  • COUNT (wyrażenie_kolumny lub) nie zrobi tego.

Oznacza to, COUNT(any_non_null_column)że da to samo co COUNT(*)oczywiście, ponieważ nie ma wartości NULL powodujących różnice.

Zasadniczo COUNT(*)powinno być lepiej, ponieważ można użyć dowolnego indeksu, ponieważ COUNT(column_or_expression)może nie być indeksowany lub SARGable

Z ANSI-92 (poszukaj „ Scalar expressions 125”)

Walizka:

a) Jeśli określono COUNT (*), wówczas wynikiem jest liczność T.

b) W przeciwnym razie niech TX będzie tabelą jednokolumnową, która jest wynikiem zastosowania <wyrażenie wartości> do każdego wiersza T i wyeliminowania wartości zerowych. Jeśli jedna lub więcej wartości zerowych zostanie wyeliminowanych, wówczas zostanie spełniony warunek ukończenia: ostrzeżenie - wartość zerowa wyeliminowana w funkcji set.

Te same zasady dotyczą przynajmniej SQL Server i Sybase

Uwaga: COUNT (1) jest taki sam jak COUNT (*), ponieważ 1 jest wyrażeniem, które nie ma wartości null.


4
Dla kompletności: Oracle użyje skanu indeksu na zindeksowanej kolumnie niepustej, jeśli count(*)jest używana.
a_horse_w_no_name

Myślałem, że trzy możliwe opcje są COUNT(*), COUNT(<constant>)i COUNT(<column name>)że wszystkie trzy mogą być poprzedzone znakiem ALLlub DISTINCT(domyślnie ALLjeśli pominięte). Zastanawiam się tylko, jakiego wyrażenia można użyć w tym, co mówisz _or_expression?
poniedziałek

2
@oneday, COUNT(1)gdy jako bezużyteczny przykład, jest taki sam jak COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)jako przykład zliczający wiersze, w których a> b.
ypercubeᵀᴹ

16

W każdej ostatniej (tj. 8.x + ) wersji Oracle robią to samo . Innymi słowy, jedyną różnicą jest semantyczna:

select count(*) from any_table

jest łatwo czytelne i oczywiste, co próbujesz zrobić, i

select count(any_non_null_column) from any_table

jest trudniejszy do odczytania, ponieważ

  1. to jest dłuższe
  2. jest mniej rozpoznawalny
  3. musisz zastanowić się, czy any_non_null_columntak naprawdę jest egzekwowane jakonot null

Krótko mówiąc, użyjcount(*)



1

W książce Oracle8i Certified Professional DBA Certification Exam Guide (ISBN 0072130601) , strona 78 mówi, że COUNT (1) faktycznie będzie działać szybciej niż COUNT (*), ponieważ w grę wchodzą określone mechanizmy sprawdzania słownika danych dla zerowalności każdej kolumny (lub przynajmniej pierwsza kolumna z zerową wartością zerową) przy użyciu COUNT (*) . COUNT (1) omija te mechanizmy.

Kody MySQL dla „SELECT COUNT (1) w tblname;” w tabelach MyISAM, czytając nagłówek tabeli dla liczby tabel. InnoDB liczy się za każdym razem.

Aby sprawdzić, czy COUNT (1) będzie działać szybciej niż COUNT (*) w sposób agnostyczny z bazą danych, po prostu uruchom następujące czynności i oceń sam czas działania:

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

To sprawia, że ​​funkcja COUNT działa na tym samym poziomie, niezależnie od silnika pamięci lub RDBMS.


8
Przewodnik egzaminacyjny jest nieprawidłowy. W Oracle liczba (*) = liczba (1) (przynajmniej po wersji 7). Zobacz asktom.oracle.com/pls/asktom/… (już wspomniany przez @JackPDouglas)
Leigh Riffel

3
Ciekawy. COUNT (*) nie powinien wcale sprawdzać kolumn zgodnie ze specyfikacją ANSI. Jakiś czas temu został poproszony na SO dla SQL Server zbyt stackoverflow.com/questions/1221559/count-vs-count1/…
gbn

@gbn, @Leigh Riffel, @bernd_k Dziękujemy za wejście i przypomnienie, żebym czytał i uczył się więcej, zwłaszcza, że ​​od dłuższego czasu nie pracuję z Oracle.
RolandoMySQLDBA
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.