<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MySQL中count(*)、count(主鍵id)、count(字段)和count(1)那種效率更高...

          共 1072字,需瀏覽 3分鐘

           ·

          2020-12-01 03:16

          66ef083418179f374b0ad7ac914090a7.webp


          在select count(?) from t這樣的查詢語句里面,count(*)、count(主鍵id)、count(字段)和count(1)等不同用法的性能,有哪些差別。


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


          這里,首先你要弄清楚count()的語義。count()是一個聚合函數(shù),對于返回的結(jié)果集,一行行地判斷,如果count函數(shù)的參數(shù)不是NULL,累計值就加1,否則不加。最后返回累計值。


          所以,count(*)、count(主鍵id)和count(1) 都表示返回滿足條件的結(jié)果集的總行數(shù);而count(字段),則表示返回滿足條件的數(shù)據(jù)行里面,參數(shù)“字段”不為NULL的總個數(shù)。


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

          1. server層要什么就給什么;

          2. InnoDB只給必要的值;

          3. 現(xiàn)在的優(yōu)化器只優(yōu)化了count(*)的語義為“取行數(shù)”,其他“顯而易見”的優(yōu)化并沒有做。


          這是什么意思呢?接下來,我們就一個個地來看看。


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


          對于count(1)來說,InnoDB引擎遍歷整張表,但不取值。server層對于返回的每一行,放一個數(shù)字“1”進(jìn)去,判斷是不可能為空的,按行累加。

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


          對于count(字段)來說

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

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

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


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


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


          當(dāng)然,MySQL專門針對這個語句進(jìn)行優(yōu)化,也不是不可以。但是這種需要專門優(yōu)化的情況太多了,而且MySQL已經(jīng)優(yōu)化過count(*)了,你直接使用這種用法就可以了。


          所以結(jié)論是:

          按照效率排序的話,count(字段)


          我們提到了在不同引擎中count(*)的實現(xiàn)方式是不一樣的,也分析了用緩存系統(tǒng)來存儲計數(shù)值存在的問題。


          其實,把計數(shù)放在Redis里面,不能夠保證計數(shù)和MySQL表里的數(shù)據(jù)精確一致的原因,是這兩個不同的存儲構(gòu)成的系統(tǒng),不支持分布式事務(wù),無法拿到精確一致的視圖。而把計數(shù)值也放在MySQL中,就解決了一致性視圖的問題。


          InnoDB引擎支持事務(wù),我們利用好事務(wù)的原子性和隔離性,就可以簡化在業(yè)務(wù)開發(fā)時的邏輯。這也是InnoDB引擎?zhèn)涫芮嗖A的原因之一。

          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美第一草草 | 久久网一区 | 成人无码中文字幕 | 超碰大香蕉精品国产 | 日本三级精品视频 |