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(*)