5 Aralık 2022 Pazartesi

COUNT(*) vs COUNT(1)

Giriş
Özet : Kısaca COUNT(*) ve COUNT(1) NULL değerler de dahil tüm satırları sayarlar. Çoğu veri tabanında bu ikisi arasında bir fark yoktur ama PostgreSQL açısından var.

Uzun Açıklama
Açıklaması şöyle. Yani aslında COUNT(*) ve COUNT(1) arasında bir performans farkı olmamalı
- COUNT(*) counts all the tuples in a group
- COUNT(<expr>) counts all the tuples in a group for which <expr> evaluates to something that IS NOT NULL
...
Now that we know the theory behind these COUNT expressions, what’s the difference between COUNT(*) and COUNT(1). There is none, effectively. The 1 expression in COUNT(1) evaluates a constant expression for each row in the group, and it can be proven that this constant expression will never evaluate to NULL, so effectively, we’re running COUNT(*), counting ALL the rows in the group again.
Ancak PostgreSQL performans farkı gösteriyor deniliyor. Açıklaması şöyle. Dolayısıyla COUNT(*) kullanmak daha iyi olabilir.
As it is now in 2019, given the database versions mentioned above, unfortunately, there is a significant difference between COUNT(*) and COUNT(1) in PostgreSQL. Luckily (and this is rare in SQL), all the other dialects don’t care and thus, consistently using COUNT(*), rather than COUNT(1) is a slightly better choice for ALL measured database products from this article.
COUNT(*) İçin Bazı Notlar
COUNT(*) tuple'dan kaç tane olduğunu gösterir. Açıklaması şöyle
Why is count(*) efficient?
When you use count(*), the database engine will use an index to count the rows. T
COUNT(*) ile LEFT JOIN yaparsak NULL sütun da olsa bir tuple olduğu için 1 sayılır

Örnek
Elimizde şöyle bir SQL olsun. Burada actor ve film veri tabanları LEFT JOIN ile birleştiriliyor. Oyuncular ve film sayılarını gösteriyor.
SELECT actor_id, a.first_name, a.last_name, COUNT(*) AS count
FROM actor AS a
LEFT JOIN film_actor AS fa USING (actor_id)
LEFT JOIN film AS f USING (film_id)
GROUP BY actor_id
ORDER BY c ASC, actor_id ASC;
Çıktı şöyle. SUSAN DAVIES hiç filmi olmadığı halde 1 çıktısı verdi. Çünkü COUNT(*) kaç satır olduğunu gösterir.
actor_id|first_name |last_name   |count |
--------|-----------|------------|----- |
     201|SUSAN      |DAVIS       | 1    |
     148|EMILY      |DEE         |14    |
      35|JUDY       |DEAN        |15    |
     199|JULIA      |FAWCETT     |15    |
     186|JULIA      |ZELLWEGER   |16    |
      31|SISSY      |SOBIESKI    |18    |
      71|ADAM       |GRANT       |18    |
       1|PENELOPE   |GUINESS     |19    |
      30|SANDRA     |PECK        |19    |
Bu sefer COUNT(*) yerine COUNT(film_id) yapıyoruz. 
SELECT actor_id, a.first_name, a.last_name, COUNT(film_id) AS c
FROM actor AS a
LEFT JOIN film_actor AS fa USING (actor_id)
LEFT JOIN film AS f USING (film_id)
GROUP BY actor_id
ORDER BY c ASC, actor_id ASC;
Çıktı şöyle
actor_id|first_name |last_name   |c |
--------|-----------|------------|--|
     201|SUSAN      |DAVIS       | 0|
     148|EMILY      |DEE         |14|
      35|JUDY       |DEAN        |15|
     199|JULIA      |FAWCETT     |15|
     186|JULIA      |ZELLWEGER   |16|
      31|SISSY      |SOBIESKI    |18|
      71|ADAM       |GRANT       |18|
       1|PENELOPE   |GUINESS     |19|
      30|SANDRA     |PECK        |19|



Hiç yorum yok:

Yorum Gönder