Innodb存儲(chǔ)引擎count()計(jì)數(shù)性能比較

0.前言

MySQL中有九種存儲(chǔ)引擎,其中主要的兩種引擎分別是:

  • MyISAM
  • InnoDB

MySQL在5.5版本之前的默認(rèn)引擎為MyISAM蜀漆,從5.5版本開(kāi)始默認(rèn)的存儲(chǔ)引擎為InnoDB谅河。

MyISAM不支持事務(wù)特性,而InnoDB支持事務(wù)。

  • 查看引擎

    mysql>SHOW ENGINES;
    Engine              Support     Transactions
    ------------------  -------     ------------
    FEDERATED           NO          (NULL) 
    MRG_MYISAM          YES         NO
    MyISAM              YES         NO
    BLACKHOLE           YES         NO
    CSV                 YES         NO
    MEMORY              YES         NO
    ARCHIVE             YES         NO
    InnoDB              DEFAULT     YES
    PERFORMANCE_SCHEMA  YES         NO
    
  • 如何查看指定數(shù)據(jù)庫(kù)的表結(jié)構(gòu)

    mysql>USE shop;
    mysql>SHOW TABLE STATUS;
    Name          Engine  Version  Row_format    Rows  Avg_row_length
    ------------  ------  -------  ----------  ------  --------------
    shop_order    InnoDB       10  Compact         23             712
    shop_product  InnoDB       10  Compact          4            4096
    shop_user     InnoDB       10  Compact          2            8192
    

MyISAM存儲(chǔ)引擎中绷耍,會(huì)把一個(gè)表的總行數(shù)存儲(chǔ)在磁盤(pán)上吐限。而InnoDB存儲(chǔ)引擎由于多版本并發(fā)控制(MVCC)機(jī)制,對(duì)于count(*)應(yīng)該返回多少行并不確定锨天,只能把數(shù)據(jù)一行一行從引擎中讀出毯盈,然后累積計(jì)數(shù),無(wú)法將總行數(shù)存儲(chǔ)在磁盤(pán)中病袄。

1.InnoDB引擎count(*)計(jì)數(shù)

1.1存在問(wèn)題

假設(shè)表t中現(xiàn)在有 10000 條記錄搂赋,我們?cè)O(shè)計(jì)了三個(gè)用戶并行的會(huì)話。

  • 會(huì)話 A 先啟動(dòng)事務(wù)并查詢一次表的總行數(shù)益缠;
  • 會(huì)話 B 啟動(dòng)事務(wù)脑奠,插入一行后記錄后,查詢表的總行數(shù)幅慌;
  • 會(huì)話 C 先啟動(dòng)一個(gè)單獨(dú)的語(yǔ)句宋欺,插入一行記錄后,查詢表的總行數(shù)胰伍。

我們假設(shè)從上到下是按照時(shí)間順序執(zhí)行的挣跋,同一行語(yǔ)句是在同一時(shí)刻執(zhí)行的绪妹。

數(shù)據(jù)庫(kù)事務(wù)會(huì)話A口蝠、B镣陕、C的執(zhí)行過(guò)程

你會(huì)看到,在最后一個(gè)時(shí)刻渗饮,三個(gè)會(huì)話 A但汞、B、C 會(huì)同時(shí)查詢表 t 的總行數(shù)互站,但拿到的結(jié)果卻不同私蕾。

因?yàn)镮nnoDB引擎的默認(rèn)隔離級(jí)別是可重復(fù)讀,在代碼上就是通過(guò)多版本并發(fā)控制(MVCC)實(shí)現(xiàn)的胡桃,每一行記錄都要判斷是否對(duì)本會(huì)話(Session)是否可見(jiàn)踩叭,對(duì)于count(*)請(qǐng)求來(lái)說(shuō),只能把數(shù)據(jù)一行一行讀出依次判斷翠胰。

1.2數(shù)據(jù)庫(kù)保存計(jì)數(shù)

由于在InnoDB的可重復(fù)讀隔離級(jí)別下懊纳,每一個(gè)會(huì)話創(chuàng)建的視圖不一定一致,導(dǎo)致count(*)計(jì)數(shù)時(shí)結(jié)果的不一致亡容,這也就是為什么InnoDB引擎不能像MyISAM引擎將表的總行數(shù)固定寫(xiě)到磁盤(pán)中(MyISAM不支持事務(wù)特性)。那么解決這一問(wèn)題的方式大致可以分為兩種:

  • 利用緩存系統(tǒng)保存計(jì)數(shù)
  • 利用數(shù)據(jù)庫(kù)表保存計(jì)數(shù)

其中利用緩存系統(tǒng)(如Redis)保存計(jì)數(shù)冤今,由于不能支持事務(wù)的強(qiáng)一致性闺兢,同樣會(huì)導(dǎo)致數(shù)據(jù)不一致的結(jié)果,具體例子如下:

緩存系統(tǒng)會(huì)話A、B的執(zhí)行過(guò)程

此時(shí)屋谭,會(huì)話B并不能查詢到新插入的數(shù)據(jù)R脚囊,但是計(jì)數(shù)值已經(jīng)加了1。雖然Redis能正常工作桐磁,但是這個(gè)計(jì)數(shù)值在邏輯上是不精確的悔耘。

而利用數(shù)據(jù)庫(kù)的事務(wù)特性就能實(shí)現(xiàn)邏輯上的一致性,如下圖所示

數(shù)據(jù)庫(kù)事務(wù)會(huì)話A我擂、B的執(zhí)行過(guò)程

由于InnoDB默認(rèn)隔離級(jí)別為可重復(fù)讀衬以,由于會(huì)話B在會(huì)話A未提交事務(wù)之前開(kāi)啟了事務(wù),所以會(huì)話A開(kāi)啟的事務(wù)視圖與會(huì)話B開(kāi)啟的事務(wù)視圖是一致的校摩,同時(shí)會(huì)話A的計(jì)數(shù)值加1操作對(duì)于會(huì)話B也是不可見(jiàn)的看峻,這就能實(shí)現(xiàn)會(huì)話B查詢最近100條記錄在邏輯的一致性。

2.InnoDB引擎下count()性能比較

count():返回對(duì)應(yīng)列值不為null的行數(shù)

2.1count(*)

由于聚簇索引下(即主鍵索引)的索引樹(shù)每個(gè)葉子節(jié)點(diǎn)都是整行數(shù)據(jù)衙吩,而非聚簇索引的索引樹(shù)葉子節(jié)點(diǎn)存儲(chǔ)的是索引值互妓,所以Server層優(yōu)化器對(duì)于count()進(jìn)行計(jì)數(shù)時(shí),會(huì)選擇非聚簇索引中最小的索引樹(shù)來(lái)遍歷坤塞。*并不取值進(jìn)行判斷冯勉。

2.2count(1)

InnoDB引擎會(huì)遍歷整張表,但不取值摹芙。Server層對(duì)于返回的每一行灼狰,放入一個(gè)數(shù)字”1“進(jìn)去。判斷不可能為空瘫辩,按行累加伏嗜。

2.3count(主鍵id)

InnoDB 引擎會(huì)遍歷整張表,把每一行的 id 值都取出來(lái)伐厌,返回給 server 層承绸。server 層拿到 id 后,判斷是不可能為空的挣轨,就按行累加军熏。

count(1) 執(zhí)行得要比 count(主鍵 id) 快。因?yàn)?strong>從引擎返回 id 會(huì)涉及到解析數(shù)據(jù)行卷扮,以及拷貝字段值的操作荡澎。

2.4count(字段)

  1. 如果這個(gè)“字段”是定義為 not null 的話,一行行地從記錄里面讀出這個(gè)字段晤锹,判斷不能為 null摩幔,按行累加
  2. 如果這個(gè)“字段”定義允許為 null鞭铆,那么執(zhí)行的時(shí)候或衡,判斷到有可能是 null,還要把值取出來(lái)再判斷一下,不是 null 才累加封断。

查找效率:count(*) ≈ count(1) > count(主鍵id) >= count(字段)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斯辰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子坡疼,更是在濱河造成了極大的恐慌彬呻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柄瑰,死亡現(xiàn)場(chǎng)離奇詭異闸氮,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)狱意,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)湖苞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人详囤,你說(shuō)我怎么就攤上這事财骨。” “怎么了藏姐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵隆箩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我羔杨,道長(zhǎng)捌臊,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任兜材,我火速辦了婚禮理澎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘曙寡。我一直安慰自己糠爬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布举庶。 她就那樣靜靜地躺著执隧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪户侥。 梳的紋絲不亂的頭發(fā)上镀琉,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音蕊唐,去河邊找鬼屋摔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛替梨,可吹牛的內(nèi)容都是我干的钓试。 我是一名探鬼主播署尤,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼亚侠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起俗扇,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤硝烂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后铜幽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體滞谢,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年除抛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狮杨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡到忽,死狀恐怖橄教,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情喘漏,我是刑警寧澤护蝶,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站翩迈,受9級(jí)特大地震影響持灰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜负饲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一堤魁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧返十,春花似錦妥泉、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至检诗,卻和暖如春匈仗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逢慌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工悠轩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人攻泼。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓火架,卻偏偏與公主長(zhǎng)得像鉴象,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子何鸡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容