MySQL count

https://www.jianshu.com/p/1b0a1f641e80]數據庫

不一樣引擎count(*)實現方式不一樣

  • MyISAM引擎把一個表的總行數記錄在了磁盤上,執行count(*)會直接返回這個數值,效率很高。
  • InnoDB,執行count(*),須要把數據一行行的從引擎中讀出來,而後累積計數。

InnoDB對count(*)的優化

  • 咱們知道,InnoDB是索引組織表,主鍵索引的葉子節點保存的是數據;普通索引的葉子節點保存的是主鍵值。因此,普通索引比主鍵索引小,對於count(*)這樣的操做,遍歷哪一個索引樹獲得的結果邏輯上是同樣的,所以,MySQL優化器會找到最小的索引樹來遍歷,在保證邏輯正確的前提下,儘可能減小掃描的數據量,是數據庫系統設計的通用法則之一。

show table status與count(*)

  • show table status命令輸出結果中有一個TABLE_ROW值,但不能代替cout(*),由於它是經過採樣統計計算的,偏差較大(可能達到40%-50%)。

聚合函數count()

  • count()是一個聚合函數,對於返回結果,一行行的判斷,若是count函數的參數不是NULL,累計值就+1,不然不加,最後返回累計值。
  • count(*)、count(id)、count(1)都表示返回知足查詢條件的結果集的總行數;count(字段),表示返回知足條件的數據行裏面參數字段不爲NULL的結果的總個數。

不一樣count參數性能對比

    • count(主鍵id):InnoDB引擎會遍歷整張表,把每一行id值都取出來,返給server層。server層拿到id後,判斷是不可能爲空的,就按行累加,再也不對每一個值進行NULL判斷。
    • count(1):InnoDB引擎會遍歷整張表,但不取值。server層對於返回的每一行,放一個數字「1」進去,判斷是不可能爲空的,按行累加,再也不對每一個值進行NULL判斷。
        count(1)比count(主鍵id)執行的要快,由於從引擎放回id會涉及解析數據行,以及拷貝字段值的操做。
    • count(字段):
        一、若是參數字段定義NOT NULL,判斷是不可能爲空的,按行累加,再也不對每一個值進行NULL判斷。
        二、若是參數字段定義容許爲NULL,那麼執行的時候,判斷多是NULL,還要把值取出來再判斷一下,不是NULL才累加。
        這也是定義字段時建議設置NOT NULL的緣由之一。
    • count(*):前面說過,InnoDB專門對它作了優化
    • 結論:對於InnoDB引擎,按效率排序,count(字段) < count(主鍵id) < count(1) ≈ count(*),建議儘可能使用count(*)
相關文章
相關標籤/搜索