最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL性能之count* count1 count列對比示例

 更新時間:2022年10月09日 11:29:49   作者:架構(gòu)精進之路  
這篇文章主要為大家介紹了MySQL性能之count* count1 count列對比示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

正文

最近的工作中,我聽到組內(nèi)兩名研發(fā)同學在交流數(shù)據(jù)統(tǒng)計性能的時候,聊到了以下內(nèi)容:

數(shù)據(jù)統(tǒng)計你怎么能用 count(*) 統(tǒng)計數(shù)據(jù)呢,count(*) 太慢了,要是把數(shù)據(jù)庫搞垮了那不就完了么,趕緊改用 count(1),這樣比較快......

有點兒好奇,難道 count(1) 的性能真的就比 count(*) 要好嗎?

印象中網(wǎng)上有很多的文章都有過類似問題的討論,那 MySQL 統(tǒng)計數(shù)據(jù)總數(shù) count(*) 、count(1)和count(列名) 哪個性能更優(yōu)呢?今天我們就來聊一聊這個問題。

count() 性能與啥相關(guān)?

在討論問題之前,我們需要先搞明白一件事:MySQL 中 count() 的性能到底與什么相關(guān)呢?

一件東西,我們知道如何取,必定需要提前知道如何存放才行,那我們可以初步判定,count() 性能應該與存儲引擎相關(guān)!

我們都知道,MySQL 常見的存儲引擎有兩種:MyISAM 和 InnoDB

在這兩種存儲引擎下,MySQL 對于使用 count()  返回結(jié)果的流程是不一樣的:

  • **MyISAM引擎:**每張表的總行數(shù)是存儲在磁盤上,所以當執(zhí)行 count() 時,是直接從磁盤拿到這個值返回,能夠快速返回。

但要是在后面加了where查詢條件時,統(tǒng)計總數(shù)也沒有像想象中那么快了。

  • **InnoDB 引擎:**執(zhí)行 count(),需要將數(shù)據(jù)一行一行地讀,再統(tǒng)計總數(shù)。

看到這里,可能你會有這樣的疑問:

Q:為什么 InnoDB 引擎不像 MyISAM 引擎一樣,把表總記錄存儲起來呢?

這個問題非常好,在回答這個問題之前,我們先來了解一下 MVCC 是個什么東東。

MVCC 簡介

所謂MVCC,全稱:Multi-Version Concurrency Control,即多版本并發(fā)控制。

MVCC 是一種并發(fā)控制的方法,一般在數(shù)據(jù)庫管理系統(tǒng)中,實現(xiàn)對數(shù)據(jù)庫的并發(fā)訪問,在編程語言中實現(xiàn)事務內(nèi)存。

MVCC 在 MySQL InnoDB 中的實現(xiàn)主要是為了提高數(shù)據(jù)庫并發(fā)性能,用更好的方式去處理讀-寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發(fā)讀。

就是因為要實現(xiàn)多版本并發(fā)控制,所以才導致 InnoDB 引擎不能直接存儲表總記錄數(shù)。因為每個事務獲取到的一致性視圖都是不一樣的,所以返回的數(shù)據(jù)總記錄也是不一致的。

到這里,相信你已經(jīng)知道 InnoDB 引擎為什么不像 MyISAM 引擎一樣把表總記錄存儲起來了,簡單理解原因就是:InnoDB 支持事務,MyISAM 不支持事務。

MySQL 對 count() 的優(yōu)化

我們知道了count() 性能與存儲引擎相關(guān),那 MySQL 在執(zhí)行 count() 操作的時候有沒有對其性能做些優(yōu)化呢?

答案是肯定有的!

InnoDB 是索引組織表,主鍵索引樹的葉子節(jié)點是數(shù)據(jù),而普通索引樹的葉子節(jié)點是主鍵值。因此,普通索引樹比主鍵索引樹小很多。對于count(*)這樣的操作,遍歷哪個索引樹得到的結(jié)果邏輯上都是一樣的。因此,MySQL優(yōu)化器會找到最小的那棵樹來遍歷。

如果你使用過 show table status 命令的話,就會發(fā)現(xiàn)這個命令的輸出結(jié)果里面也有一個 rows 值用于顯示這個表當前有多少行。

相信有人肯定會問,是不是這個 rows 值就能代替 count() 了嗎?

其實不能,rows 這個是從從采樣估算得來的,因此它也是不是準確。

官方文檔說是在40%到50%,所以此行數(shù) rows 是不能直接使用的,如下所示:

查詢性能 PK 大起底

基于 MySQL 的 Innodb 存儲引擎,統(tǒng)計表的總記錄數(shù)下面這幾種做法,到底哪種效率最高?

count(主鍵id)

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

count(1)

會統(tǒng)計表中的所有的記錄數(shù),包含字段為 null 的記錄。

同樣遍歷整張表,但不取值,server 層對返回的每一行,放一個數(shù)字1進去,判斷是不可能為空的,按行累加。

count(字段)

分為兩種情況,字段定義為 not null 和 null:

1)為 not null 時:逐行從記錄里面讀出這個字段,判斷不為 null,累加;

2)為 null 時:執(zhí)行時,判斷到有可能是 null,還要把值取出來再判斷一下,不是 null 才累加。

count(*)

需要注意的是,并不是帶了 * 就把所有值取出來,而是 MySQL 做了專門的優(yōu)化,count(*) 肯定不是null,按行累加。

count(1) 和 count(*) 對比

當表的數(shù)據(jù)量大些時,對表作分析之后,使用 count(1)還要比使用 count(*)用時多了!

從執(zhí)行計劃來看, count(1)count(*)的效果是一樣的。但是在表做過分析之后, count(1) 會比 count(*)的用時少些(1w以內(nèi)數(shù)據(jù)量),不過差不了多少。

如果 count(1)是聚索引,那肯定是 count(1)快,但是差的很小。因為 count(*)自動會優(yōu)化指定到那一個字段,所以沒必要去 count(1),用 count(*) sql會幫你完成優(yōu)化的,因此:count(1)count(*)基本沒有差別!

總結(jié)

基于 MySQL 的 InnoDB 存儲引擎,統(tǒng)計表的總記錄數(shù)按照效率排序:

count(字段) < count(主鍵id) < count(1)≈count(*)

效率最高是 count(*),并不是count(1),所以建議盡量使用 count(*)。

執(zhí)行效果上:

count(*)包括了所有的列,相當于行數(shù),在統(tǒng)計結(jié)果的時候,不會忽略列值為null

count(1)包括了忽略所有列,用1代表代碼行,在統(tǒng)計結(jié)果的時候,不會忽略列值為null

count(列名)只包括列名那一列,在統(tǒng)計結(jié)果的時候,會忽略列值為空(這里的空不是只空字符串或者0,而是表示null 的計數(shù),即某個字段值為null 時,不統(tǒng)計。

執(zhí)行效率上:

  • 列名為主鍵, count(列名) 會比 count(1)
  • 列名不為主鍵, count(1) 會比 count(列名)
  • 如果表多個列并且沒有主鍵,則 count(1) 的執(zhí)行效率優(yōu)于 count(*)
  • 如果有主鍵,則 select count(主鍵) 的執(zhí)行效率是最優(yōu)的
  • 如果表只有一個字段,則 select count(*)最優(yōu)。

希望今天的講解對大家有所幫助,謝謝!

更多關(guān)于MySQL count性能對比的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • mysql lpad函數(shù)和rpad函數(shù)的使用詳解

    mysql lpad函數(shù)和rpad函數(shù)的使用詳解

    MySQL中的LPAD和RPAD函數(shù)用于字符串填充,LPAD從左至右填充,RPAD從右至左填充,兩者都可指定填充長度和填充字符,如果填充長度小于原字符串長度,則會截取原字符串相應長度的字符
    2025-02-02
  • Mysql8導入數(shù)據(jù)到Mysql5.7的實現(xiàn)步驟

    Mysql8導入數(shù)據(jù)到Mysql5.7的實現(xiàn)步驟

    Mysql8的默認字符集為utf8mb4,當我們有需求要把Mysql8的數(shù)據(jù)導入到Mysql5.7時,就會出現(xiàn)不支持,本文主要介紹了2種解決方法,具有一定的參考價值,感興趣的可以了解一下
    2022-03-03
  • MySQL數(shù)據(jù)庫Event定時執(zhí)行任務詳解

    MySQL數(shù)據(jù)庫Event定時執(zhí)行任務詳解

    這篇文章主要介紹了MySQL數(shù)據(jù)庫Event定時執(zhí)行任務
    2017-12-12
  • 全面詳解MySQL單行函數(shù)分析

    全面詳解MySQL單行函數(shù)分析

    MySQL常見的函數(shù)分為單行函數(shù)和分組函數(shù),單行函數(shù)包含字符函數(shù)、數(shù)學函數(shù)、日期函數(shù)、流程控制函數(shù)等,下面就詳細的來介紹一下MySQL單行函數(shù)
    2023-10-10
  • MySQL中定時器的底層實現(xiàn)原理及使用方法

    MySQL中定時器的底層實現(xiàn)原理及使用方法

    定時器可以用于定期執(zhí)行特定的SQL語句、備份數(shù)據(jù)、生成報表等操作,本文將詳細介紹MySQL中定時器的底層實現(xiàn)機制以及如何使用它
    2023-07-07
  • 一文搞懂MySQL索引頁結(jié)構(gòu)

    一文搞懂MySQL索引頁結(jié)構(gòu)

    本文主要介紹了MySQL索引頁結(jié)構(gòu),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • MySQL主從配置學習筆記

    MySQL主從配置學習筆記

    在本篇文章里小編給大家整理的是關(guān)于MySQL主從配置學習筆記相關(guān)內(nèi)容,需要的朋友們可以學習下。
    2020-03-03
  • mysql alter table 修改表命令詳細介紹

    mysql alter table 修改表命令詳細介紹

    MYSQL ALTER TABLE命令用于修改表結(jié)構(gòu),例如添加/修改/刪除字段、索引、主鍵等等,本文章通過實例向大家介紹MYSQL ALTER TABLE語句的使用方法,需要的朋友可以參考一下。
    2016-10-10
  • MySQL創(chuàng)建數(shù)據(jù)庫并支持中文字符的操作方法

    MySQL創(chuàng)建數(shù)據(jù)庫并支持中文字符的操作方法

    這篇文章主要介紹了MySQL創(chuàng)建數(shù)據(jù)庫并支持中文字符的操作方法,本文給大家介紹的非常詳細,對大家的學習或工作具體一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • MySQL 性能優(yōu)化的最佳20多條經(jīng)驗分享

    MySQL 性能優(yōu)化的最佳20多條經(jīng)驗分享

    今天,數(shù)據(jù)庫的操作越來越成為整個應用的性能瓶頸了,這點對于Web應用尤其明顯。關(guān)于數(shù)據(jù)庫的性能,這并不只是DBA才需要擔心的事,而這更是我們程序員需要去關(guān)注的事情。
    2010-07-07

最新評論

苏尼特右旗| 阜阳市| 申扎县| 柳林县| 南宫市| 甘德县| 梁山县| 建阳市| 滦南县| 襄樊市| 左权县| 东源县| 阿拉善右旗| 舞阳县| 襄汾县| 苍南县| 沐川县| 玛沁县| 贞丰县| 美姑县| 阿勒泰市| 新乡市| 宽甸| 包头市| 新沂市| 旌德县| 同江市| 峨眉山市| 星子县| 大姚县| 云南省| 柯坪县| 军事| 郸城县| 阿鲁科尔沁旗| 营口市| 上林县| 威海市| 焉耆| 永嘉县| 永平县|