大家好,我是程式設計師魚皮。歡迎螢幕前的各位來到今天的模擬面試現場,接下來我會出一道經典的後端面試題,你只需要進行 4 個簡單的選擇,就能判斷出來你的水平是新手(3k)、初級(10k)、中級(15k)還是高階(30k)!
請聽題:
題目
MySQL 資料庫中的 count(1)、count(*)、count(欄位)有什麼區別?
請回答
1、它們在功能上有區別麼?
A:有區別
B:沒區別
答案
有區別。雖然在 MySQL 中,count(*)、count(1) 和 count(欄位名) 都是用來 統計行數的聚合函式 。
但 count(*) 和 count(1) 會統計表中所有行的數量,包括 null 值(不會忽略任何一行資料);而 count(欄位名) 只會統計指定欄位不為 null 的行數。
恭喜答對的朋友,3k 的 offer 到手啦!
2、count(*) 和 count(1) 誰更快?
A:count(*)
B:count(1)
C:沒區別
答案
效率一致,沒區別。
關於 count(1) 和 count(*) 誰更快的問題,網上眾說紛紜,如果背了不專業的八股文,可能答案就選錯咯~
有點經驗的程式設計師,在遇到不確定的問題時,當然要去源頭親自求證,得去看官網怎麼說。如圖:
官網表示 There is no performance difference
,即二者沒有效能上的區別!
對於 count(欄位) 的查詢就是全表掃描,正常情況下它還需要判斷欄位是否是 null 值,因此理論上會比 count(1) 和 count(*) 慢。
但是如果欄位不為 null,例如是主鍵或具有非空約束,那麼理論上效能也差不多。而且本質上它們的統計功能不一樣,在需要統計 null 的時候,只能用 count(1) 和 count(*),不需要統計 null 的時候只能用 count(欄位),所以也不用太糾結效能問題。
恭喜答對的朋友,10k 的 offer 到手啦!
3、用 count(*) 統計有千萬條記錄的表的總資料量,快不快?
A:快
B:慢
C:其他
答案
這是一道簡單的場景題,有經驗的程式設計師,本能地會想到 具體情況具體分析 。
MySQL 有 2 個主流的儲存引擎 MyISAM 和 InnoDB。
在 MyISAM 引擎中,有一個內部計數器來維護表的記錄數,查詢時可以直接返回表的行數,而無需掃描整個表,所以 count(*) 非常快。
但是在 InnoDB 引擎中無法維護記錄總數,需要掃描整個表,所以表越大、記錄越多,count(*) 就越慢。
為什麼 InnoDB 引擎不維護記錄總數呢?因為它支援行鎖,會有很多併發修改表資料的操作,難以維護總數,還會帶來額外的效能開銷;而 MyISAM 只有表鎖,對單個表的修改序列執行,所以能維護總數。所以要針對業務場景選擇不同的 MySQL 引擎。
恭喜答對的朋友,15k 的 offer 到手啦!
4、InnoDB 引擎中,count(id) 和 count(二級索引) 哪個成本更低?
A:count(id)
B:count(二級索引)
C:其他
答案
count(二級索引) 通常成本更低。是不是沒想到?
這是對上一問的進一步追問,雖然 InnoDB 引擎中 count(*) 統計總數效能不高,但它也針對這個操作進行了一定的最佳化。
id 通常是主鍵索引,在 InnoDB 中,主鍵索引是聚簇索引,它儲存了實際的資料行。執行 count 時,InnoDB 需要遍歷整個聚簇索引來統計行數。
二級索引是指儲存了索引列和主鍵列的指標,而不包含實際的資料行。因此,二級索引相對來說更小。執行 count 時,InnoDB 只需要遍歷這個較小的二級索引,而不是整個聚簇索引,需要讀取的資料頁更少,所以成本更低。
當然,理論歸理論,具體情況具體分析,具體的效能差異取決於索引的大小和表的結構,可以用 explain 語句檢視查詢計劃和成本。
恭喜答對的朋友,30k 的 offer 到手啦!
哦不對,恭喜摸到了 30k 的門檻,繼續努力,說不定下一個技術專家就是你~
最後
透過這道題目可以發現,其實面試的時候,很多題目都是可以深挖的,挖的越深,越能體現出候選人的水平。
有同學表示:自己面試題目都答上來了,為啥還是透過不了?
別灰心,可能只是差點兒運氣,同場面試有同學比你答的更深、表達更流暢罷了。
不管怎麼樣,大家在準備面試八股文的時候,有時間的話,多思考一點、再深入一點,自己也能學到很多東西。歡迎多到我們的
你答對了幾問呢?歡迎大家在評論區留言~
更多
💻 程式設計學習交流: