Postgresql

為什麼 count(x.) 比 count() 慢?

  • March 27, 2022
explain select count(x.*) from customer x;
...
->  Partial Aggregate  (cost=27005.45..27005.46 rows=1 width=8)
 ->  Parallel Seq Scan on customer x  (cost=0.00..26412.56 rows=237156 width=994)

explain select count(*) from customer x;
...                                     

->  Partial Aggregate  (cost=27005.45..27005.46 rows=1 width=8)
 ->  Parallel Seq Scan on customer x  (cost=0.00..26412.56 rows=237156 width=0)

這裡COUNT(x.*)使width解釋結果中讀取不必要的行數據。

我認為它們應該是相同的,但似乎不是,為什麼?

從邏輯上講,兩者都是相同的 - 因為x.*總是計數,即使所有列都是NULL.

但是 Postgres 有一個單獨的實現count(*)

它根本不關心任何表達式,只考慮活動行的存在。這稍微快了一點,這總結了許多行的相關差異。

的性能損失count(x.*)隨著列數/行寬的增加而增加,並且對於像您這樣的寬行(width=994)將是相當大的。

它甚至被明確記錄

count( *) →bigint

計算輸入行數。


count( "any") →bigint

計算輸入值不為空的輸入行數。

它的要點:當您不關心表達式是否為NULL時,請count(*)改用。

有關的:

其他一些 RDBMS 沒有相同的快速路徑count(*)。OTOH,在 Postgres 中計算表中的所有行相對較慢,因為它的 MVCC 模型強制檢查行可見性。看:

引用自:https://dba.stackexchange.com/questions/309910