1. 程式人生 > 其它 >InnoDB中的的聚合函式count(?)哪個效率高?

InnoDB中的的聚合函式count(?)哪個效率高?

  MyISAM 引擎把一個表的總行數存在了磁碟上,因此執行 count(*) 的時候會直接返回這個數,效率很高;

  而 InnoDB 引擎就麻煩了,它執行 count(*) 的時候,需要把資料一行一行地從引擎裡面讀出來,然後累積計數。

  count() 是一個聚合函式,對於返回的結果集,一行行地判斷,如果 count 函式的引數不是 NULL,累計值就加 1,否則不加。最後返回累計值。

  所以,count(*)、count(主鍵 id) 和 count(1) 都表示返回滿足條件的結果集的總行數;而 count(欄位),則表示返回滿足條件的資料行裡面,引數“欄位”不為 NULL 的總個數。

  對於 count(主鍵 id) 來說,InnoDB 引擎會遍歷整張表,把每一行的 id 值都取出來,返回給 server 層。server 層拿到 id 後,判斷是不可能為空的,就按行累加。

  對於 count(1) 來說,InnoDB 引擎遍歷整張表,但不取值。server 層對於返回的每一行,放一個數字“1”進去,判斷是不可能為空的,按行累加。

  單看這兩個用法的差別的話,你能對比出來,count(1) 執行得要比 count(主鍵 id) 快。因為從引擎返回 id 會涉及到解析資料行,以及拷貝欄位值的操作。

  對於 count(欄位) 來說:

  •   如果這個“欄位”是定義為 not null 的話,一行行地從記錄裡面讀出這個欄位,判斷不能為 null,按行累加;
  •   如果這個“欄位”定義允許為 null,那麼執行的時候,判斷到有可能是 null,還要把值取出來再判斷一下,不是 null 才累加。

  但是 count(*) 是例外,並不會把全部欄位取出來,而是專門做了優化,不取值。count(*) 肯定不是 null,按行累加。

 

  所以結論是:

  按照效率排序的話,count(欄位)<count(id)<count(*)≈count(1);

  所以實際使用中如何不考慮某個欄位為空的情況,優先使用count(1)或者count(*);