mysql count聚合函數性能

count(*)、count(主鍵id) 和 count(1) 都表示返回滿足條件的結果集的總行數;
而count(字段),則表示返回滿足條件的數據行裏面,參數“字段”不爲 NULL 的總個數。

性能差別

  1. server 層要什麼就給什麼;
  2. InnoDB 只給必要的值;
  3. 現在的優化器只優化了 count(*) 的語義爲“取行數”,其他“顯而易見”的優化並沒有
    做。

對於 count(主鍵 id) 來說,InnoDB 引擎會遍歷整張表,把每一行的 id 值都取出來,返回給
server 層。server 層拿到 id 後,判斷是不可能爲空的,就按行累加。
對於 count(1) 來說,InnoDB 引擎遍歷整張表,但不取值。server 層對於返回的每一行,放一
個數字“1”進去,判斷是不可能爲空的,按行累加。
單看這兩個用法的差別的話,你能對比出來,count(1) 執行得要比 count(主鍵 id) 快。因爲從
引擎返回 id 會涉及到解析數據行,以及拷貝字段值的操作。
對於 count(字段) 來說:

  1. 如果這個“字段”是定義爲 not null 的話,一行行地從記錄裏面讀出這個字段,判斷不能
    爲 null,按行累加;
  2. 如果這個“字段”定義允許爲 null,那麼執行的時候,判斷到有可能是 null,還要把值取出
    來再判斷一下,不是 null 才累加。
    也就是前面的第一條原則,server 層要什麼字段,InnoDB 就返回什麼字段。
    但是 count() 是例外,並不會把全部字段取出來,而是專門做了優化,不取值。count() 肯定
    不是 null,按行累加。
    看到這裏,你一定會說,優化器就不能自己判斷一下嗎,主鍵 id 肯定非空啊,爲什麼不能按照
    count() 來處理,多麼簡單的優化啊。
    當然,MySQL 專門針對這個語句進行優化,也不是不可以。但是這種需要專門優化的情況太多
    了,而且 MySQL 已經優化過 count(
    ) 了,你直接使用這種用法就可以了。
    所以結論是:按照效率排序的話,count(字段)<count(主鍵 id)<count(1)≈count(),所以我
    建議你,儘量使用 count(
    )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章