mysql count(*) count(1) count(主鍵id) count(字段)區(qū)別及性能(Innodb引擎)

count(*) 的實現方式

你首先要明確的是肛走,在不同的 MySQL 引擎中焚志,count(*) 有不同的實現方式。

MyISAM 引擎把一個表的總行數存在了磁盤上胆筒,因此執(zhí)行 count(*) 的時候會直接返回這個數邮破,效率很高;

而 InnoDB 引擎就麻煩了仆救,它執(zhí)行 count(*) 的時候抒和,需要把數據一行一行地從引擎里面讀出來,然后累積計數彤蔽。

這里需要注意的是摧莽,我們在這篇文章里討論的是沒有過濾條件的 count(*),如果加了 where 條件的話顿痪,MyISAM 表也是不能返回得這么快的镊辕。

好了 下面開始我們今天博文的正式內容:

在 select count(?) from t 這樣的查詢語句里面,count(*)员魏、count(主鍵 id)丑蛤、count(字段) 和 count(1) 等不同用法的性能,有哪些差別撕阎。今天談到了 count(*) 的性能問題受裹,我就借此機會和你詳細說明一下這幾種用法的性能差別。

需要注意的是,下面的討論還是基于 InnoDB 引擎的

這里棉饶,首先你要弄清楚 count() 的語義厦章。count() 是一個聚合函數,對于返回的結果集照藻,一行行地判斷袜啃,如果 count 函數的參數不是 NULL,累計值就加 1幸缕,否則不加群发。最后返回累計值。

所以发乔,count(*)熟妓、count(主鍵 id) 和 count(1) 都表示返回滿足條件的結果集的總行數;而 count(字段)栏尚,則表示返回滿足條件的數據行里面起愈,參數“字段”不為 NULL 的總個數。

至于分析性能差別的時候译仗,你可以記住這么幾個原則:

1抬虽、server 層要什么就給什么;

2纵菌、InnoDB 只給必要的值阐污;

3、現在的優(yōu)化器只優(yōu)化了 count(*) 的語義為“取行數”产艾,其他“顯而易見”的優(yōu)化并沒有做疤剑。

對于 count(主鍵 id) 來說,InnoDB 引擎會遍歷整張表闷堡,把每一行的 id 值都取出來隘膘,返回給 server 層。server 層拿到 id 后杠览,判斷是不可能為空的弯菊,就按行累加。

對于 count(1) 來說踱阿,InnoDB 引擎遍歷整張表管钳,但不取值。server 層對于返回的每一行软舌,放一個數字“1”進去才漆,判斷是不可能為空的,按行累加佛点。

單看這兩個用法的差別的話醇滥,你能對比出來黎比,count(1) 執(zhí)行得要比 count(主鍵 id) 快。因為從引擎返回 id 會涉及到解析數據行鸳玩,以及拷貝字段值的操作阅虫。

對于 count(字段) 來說

1.如果這個“字段”是定義為 not null 的話,一行行地從記錄里面讀出這個字段不跟,判斷不能為 null颓帝,按行累加;

2.如果這個“字段”定義允許為 null窝革,那么執(zhí)行的時候购城,判斷到有可能是 null,還要把值取出來再判斷一下虐译,不是 null 才累加工猜。

也就是前面的第一條原則,server 層要什么字段菱蔬,InnoDB 就返回什么字段。

但是 count(*) 是例外史侣,并不會把全部字段取出來拴泌,而是專門做了優(yōu)化,不取值惊橱。count(*) 肯定不是 null蚪腐,按行累加。

看到這里税朴,你一定會說回季,優(yōu)化器就不能自己判斷一下嗎,主鍵 id 肯定非空啊正林,為什么不能按照 count(*) 來處理泡一,多么簡單的優(yōu)化啊。

當然觅廓,MySQL 專門針對這個語句進行優(yōu)化鼻忠,也不是不可以。但是這種需要專門優(yōu)化的情況太多了杈绸,而且 MySQL 已經優(yōu)化過 count(*) 了帖蔓,你直接使用這種用法就可以了。

所以結論是:按照效率排序的話瞳脓,count(字段)<count(主鍵 id)<count(1)≈count(*)塑娇,所以我建議你,盡量使用 count(*)劫侧。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末埋酬,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌奇瘦,老刑警劉巖棘催,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異耳标,居然都是意外死亡醇坝,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門次坡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呼猪,“玉大人,你說我怎么就攤上這事砸琅∷尉啵” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵症脂,是天一觀的道長谚赎。 經常有香客問我,道長诱篷,這世上最難降的妖魔是什么壶唤? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮棕所,結果婚禮上闸盔,老公的妹妹穿的比我還像新娘。我一直安慰自己琳省,他們只是感情好迎吵,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著针贬,像睡著了一般击费。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桦他,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天荡灾,我揣著相機與錄音,去河邊找鬼瞬铸。 笑死批幌,一個胖子當著我的面吹牛,可吹牛的內容都是我干的嗓节。 我是一名探鬼主播荧缘,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼拦宣!你這毒婦竟也來了截粗?” 一聲冷哼從身側響起信姓,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绸罗,沒想到半個月后意推,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡珊蟀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年菊值,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片育灸。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡腻窒,死狀恐怖,靈堂內的尸體忽然破棺而出磅崭,到底是詐尸還是另有隱情儿子,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布砸喻,位于F島的核電站柔逼,受9級特大地震影響,放射性物質發(fā)生泄漏割岛。R本人自食惡果不足惜卒落,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蜂桶。 院中可真熱鬧,春花似錦也切、人聲如沸扑媚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疆股。三九已至,卻和暖如春倒槐,著一層夾襖步出監(jiān)牢的瞬間旬痹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工讨越, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留两残,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓把跨,卻偏偏與公主長得像人弓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子着逐,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容