Oracle: Count(*) czy count(1) oto jest pytanie

17 września 2015, Monika Mitura

Od wielu lat na forach Oracle’owych toczy się ideologiczna walka: COUNT(*) czy COUNT(1). Każda z opcji ma swoich zagorzałych przeciwników i zwolenników.

Najczęstszym argumentem grupy popierającej korzystanie z wersji COUNT(1) jest twierdzenie, że COUNT (1) jest szybsze niż COUNT (*). Według tej teorii  COUNT (*) do zliczenia wierszy bierze wszystkie kolumny zaś COUNT (1) tylko kolumnę pierwszą, primary key – i dzięki zliczaniu po indexie zapytanie jest znacznie szybsze.

Brzmi to nawet całkiem sensownie, gdyby nie to, że jest to absolutna nieprawda.

Ogólna definicja funkcji COUNT wygląda jak poniżej:

COUNT(<expression>)

Funkcja COUNT zlicza wszystkie wystąpienia nie puste (non null) wyrażenia <expression>.

COUNT(1)  jest niczym innym niż COUNT(<EXPRESSION>)  gdzie expression = 1 czyli wartością non-null!  Funkcja zlicza ilość rekordów w tabeli, dla których wyrażenie <expression> nie jest nulem -> a wartość 1 oczywiście nie jest nulem.

COUNT(*)  

Tutaj nie ma wiele do wyjaśniania – funkcja zlicza po prostu wszystkie rekordy w tabeli.

COUNT(*) COUNT(MANAGER_ID) COUNT(1) COUNT(‘BANANA’)
107 106 107 107

Jak widać na powyższym przykładzie czy wykonamy count(*) czy count(1) czy może count(‘banana’) otrzymamy ten sam wynik. Wiec może powinniśmy korzystać z count(‘banana’)?

Jeśli chcemy mieć przejrzysty i czytelny kod to najbardziej odpowiednią funkcją będzie COUNT(*) . Już na pierwszy rzut oka widać, co będzie wykonywane . Gwiazdka jest dość typowym znakiem standardowo oznaczającym „wszystko” – możemy więc śmiało założyć, że zostaną zliczone wszystkie wiersze w tabeli.

Jak widać po burzliwych dyskusjach na forach  Dla COUNT(1)  sprawa już  nie jest taka oczywista  – czy funkcja zlicza tylko pierwszą kolumnę, czy wartości nie puste, czy liczy po indexie? Zdania są podzielone i każda wersja ma swoich zagorzałych zwolenników.

Podsumowując: jeśli chcemy zliczyć ilość rekordów gdzie wyrażenie expression jest non-null (np. ilość rekordów dla których kolumna manager_id jest nie pusta) w tabeli należy skorzystać z funkcji COUNT(<expression>). Jeśli zaś chcemy zliczyć WSZYSTKIE rekordy  w tabeli powinniśmy użyć funkcji COUNT(*).

No i na koniec dla wszystkich sceptyków  COUNT(*) – ostateczny argument :

Wszyscy czy chcą czy nie chcą i tak ostatecznie kończą  używając COUNT(*) –  Oracle wewnętrznie przepisuje  funkcję COUNT(1)  do postaci COUNT(*)…

 

Poniżej kilka odnośników do co ciekawszych dyskusji/postów:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:40208915257337

https://community.oracle.com/thread/613439

http://www.databaseskill.com/4564328/

http://dba.stackexchange.com/questions/2511/what-is-the-difference-between-select-count-and-select-countany-non-null-col

http://www.dbforums.com/showthread.php?1605397-difference-in-count(*)-and-count(1)

Wpis był oryginalnie opublikowany na moim blogu how2ora.blogspot.com

Tagi: , , , , , ,

Zapraszamy do kontaktu!

Pretius jest firmą tworząca oprogramowanie wspierające biznes.
Tworzymy aplikacje webowe wykorzystując: Java, Oracle DB, Oracle Apex, AngularJS.
Skontaktuj się z nami, aby porozmawiać o tym jak możemy pomóc w realizacji Twojego projektu!