簡介:
count()函數用來統計表的行數,也就是統計記錄行數,很好理解的,但面試你這么說就有點單薄了。
count()函數具體情況下的各種分析:

各類面試題總結了一下,應該遇到的話不會怕了:
1)為什么 InnoDB 不把總條數記錄下來,查詢的時候直接返回呢?
因為 InnoDB 使用了事務實現,而事務的設計使用了多版本並發控制,即使是在同一時間進行查詢,得到的結果也可能不相同,所以 InnoDB 不能把結果直接保存下來,因為這樣是不准確的。
2)能否使用 show table status 中的表行數作為表的總行數直接使用?為什么?
不能,因為 show table status 是通過采樣統計估算出來的,官方文檔說誤差可能在 40% 左右,所以 show table status 中的表行數不能直接使用。
3)InnoDB 和 MyISAM 執行 select count(*) from t,哪個效率更高?為什么?
MyISAM 效率最高,因為 MyISAM 內部維護了一個計數器,直接返回總條數,而 InnoDB 要逐行統計。
4)在 MySQL 中有對 count(*) 做優化嗎?做了哪些優化?
count(*) 在不同的 MySQL 引擎中的實現方式是不相同的,在沒有 where 條件的情況下:
- MyISAM 引擎會把表的總行數存儲在磁盤上,因此在執行 count(*) 的時候會直接返回這個這個行數,執行效率很高;
- InnoDB 引擎中 count(*) 就比較麻煩了,需要把數據一行一行的從引擎中讀出來,然后累計基數。
但即使這樣,在 InnoDB 中,MySQL 還是做了優化的,我們知道對於 count() 這樣的操作,遍歷任意索引樹得到的結果,在邏輯上都是一樣的,因此,MySQL 優化器會找到最小的那顆索引樹來遍歷,這樣就能在保證邏輯正確的前提下,盡量少掃描數據量,從而優化了 count() 的執行效率。
5)在 InnoDB 引擎中 count(*)、count(1)、count(主鍵)、count(字段) 哪個性能最高?
count(字段)<count(主鍵 id)<count(1)≈count(*) 題目解析:
- 對於 count(主鍵 id) 來說,InnoDB 引擎會遍歷整張表,把每一行的 id 值都取出來,返回給 server 層。server 層拿到 id 后,判斷是不可能為空的,就按行累加。
- 對於 count(1) 來說,InnoDB 引擎遍歷整張表,但不取值。server 層對於返回的每一行,放一個數字“1”進去,判斷是不可能為空的,按行累加。
- 對於 count(字段) 來說,如果這個“字段”是定義為 not null 的話,一行行地從記錄里面讀出這個字段,判斷不能為 null,按行累加;如果這個“字段”定義允許為 null,那么執行的時候,判斷到有可能是 null,還要把值取出來再判斷一下,不是 null 才累加。
- 對於 count(*) 來說,並不會把全部字段取出來,而是專門做了優化,不取值,直接按行累加。
所以最后得出的結果是:count(字段)<count(主鍵 id)<count(1)≈count(*)。
加油吧! 奧利給!
