日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

dbgrideh 为什么只一行_Mysql性能优化:为什么count(*)这么慢?

發布時間:2025/3/8 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dbgrideh 为什么只一行_Mysql性能优化:为什么count(*)这么慢? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

導讀

  • 在開發中一定會用到統計一張表的行數,比如一個交易系統,老板會讓你每天生成一個報表,這些統計信息少不了sql中的count函數。
  • 但是隨著記錄越來越多,查詢的速度會越來越慢,為什么會這樣呢?Mysql內部到底是怎么處理的?
  • 今天這篇文章將從Mysql內部對于count函數是怎樣處理的來展開詳細的講述。

count的實現方式

  • 在Mysql中的不同的存儲引擎對count函數有不同的實現方式。
  • MyISAM引擎把一個表的總行數存在了磁盤上,因此執行count(*)的時候會直接返回這個數,效率很高(沒有where查詢條件)。
  • InnoDB引擎并沒有直接將總數存在磁盤上,在執行count(*)函數的時候需要一行一行的將數據讀出來,然后累計總數。

為什么InnoDB不將總數存起來?

  • 說到InnoDB相信讀者總會想到其支持事務的特性,事務具有隔離性,如果將總數存起來,怎么保證各個事務之間的總數的一致性呢?不明白的看下圖:

  • 事務A和事務B中的count(*)的執行結果是不同的,因此InnoDB引擎在每個事務中返回多少行是不確定的,只能一行一行的讀出來用來判斷總數。

如何提升count效率

  • 在InnoDB對于如何提升count(*)的查詢效率,網上有多種解決辦法,這里主要介紹三種,并分析可行性。

show table status

  • show table status這個命令能夠很快的查詢出數據庫中每個表的行數,但是真的能夠替代count(*)嗎?
  • 答案是不能。原因很簡單,這個命令統計出來的值是一個「估值」,因此是不準確的,官方文檔說誤差大概在40%-50%。
  • 因此這種方法直接pass,不準確還用它干嘛。

緩存系統存儲總數

  • 這種方法也是最容易想到的,增加一行就+1,刪除一行就-1,并且緩存系統讀取也是很快,既簡單又方便的為什么不用?
  • 緩存系統和Mysql是兩個系統,比如redis和Mysql這兩個是典型的比較。兩個系統最難的就是在高并發下無法保證數據的一致性。通過以下兩圖我們來理解一下:

  • 通過上面兩張圖,無論是redis計數+1還是insert into user先執行,最終都會導致數據在邏輯上的不一致。第一張圖會出現redis計數少了,第二張圖雖然計數正確了但是并沒有查詢出插入的那一行數據。
  • 在并發系統里面,我們是無法精確控制不同線程的執行時刻的,因為存在圖中的這種操作序列,所以,我們說即使Redis正常工作,這個計數值還是邏輯上不精確的。

在數據庫保存計數

  • 通過緩存系統保存的分析得知了使用緩存無法保證數據在邏輯上的一致性,因此我們想到了直接使用數據庫來保存,有了「事務」的支持,也就保證了數據的一致性了。
  • 如何使用呢?很簡單,直接將計數保存在一張表中(table_name,total)。
  • 至于執行的邏輯只需要將緩存系統中redis計數+1改成total字段+1即可,如下圖:

  • 由于在同一個事務中,保證了數據在邏輯上的一致性。

不同count的用法

  • count()是一個聚合函數,對于返回的結果集,一行行地判斷,如果count函數的參數不是NULL,累計值就加1,否則不加。最后返回累計值。
  • count的用法有多種,分別是count(*)、count(字段)、count(1)、count(主鍵id)。那么多種用法,到底有什么差別呢?當然,「前提是沒有where條件語句」。
  • count(id):InnoDB引擎會遍歷整張表,把每一行的id值都取出來,返回給server層。server層拿到id后,判斷是不可能為空的,就按行累加。
  • count(1):InnoDB引擎遍歷整張表,但不取值。server層對于返回的每一行,放一個數字1進去,判斷是不可能為空的,按行累加。
  • count(字段):
  • 如果這個“字段”是定義為not null的話,一行行地從記錄里面讀出這個字段,判斷不能為null,按行累加;
  • 如果這個字段定義允許為null,那么執行的時候,判斷到有可能是null,還要把值取出來再判斷一下,不是null才累加。
  • count(*):不會把全部字段取出來,而是專門做了優化,不取值。count(*)肯定不是null,按行累加。
  • 所以結論很簡單:「按照效率排序的話,count(字段)<count(主鍵id)<count(1)≈count(*),所以建議讀者,盡量使用count(*)。」
  • 「注意」:這里肯定有人會問,count(id)不是走的索引嗎,為什么查詢效率和其他的差不多呢?陳某在這里解釋一下,雖然走的索引,但是還是要一行一行的掃描才能統計出來總數。

總結

  • MyISAM表雖然count(*)很快,但是不支持事務;
  • show table status命令雖然返回很快,但是不準確;
  • InnoDB直接count(*)會遍歷全表(沒有where條件),雖然結果準確,但會導致性能問題。
  • 緩存系統的存儲計數雖然簡單效率高,但是無法保證數據的一致性。
  • 數據庫保存計數很簡單,也能保證數據的一致性,建議使用。

總結

以上是生活随笔為你收集整理的dbgrideh 为什么只一行_Mysql性能优化:为什么count(*)这么慢?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 中文在线不卡 | 亚洲欧洲一区二区三区 | 精品国产乱码久久久久久108 | 性感美女被草 | 日本特黄一级片 | 在线观看国产一区二区三区 | 天堂伊人 | 女人下面喷水视频 | 国产视频1区2区3区 国产欧美一区二区精品性色99 | 老公吃小头头视频免费观看 | exo妈妈mv在线播放高清免费 | 不卡的av网站| 国产精品com| 成人黄色免费在线观看 | 91av视频在线观看 | 日日躁夜夜躁狠狠久久av | 国产又爽又色 | 日韩日b视频 | 欧日韩精品 | 国产美女被遭强高潮免费网站 | 欧美人与禽性xxxxx杂性 | 国产视频在线观看一区二区 | 17c在线观看| 日本一二区视频 | 不卡中文字幕在线 | 日韩中文字幕 | 香蕉av在线播放 | 欧美aa一级 | 老湿影院av | 亚洲色图88 | 国产三级在线免费 | 女厕厕露p撒尿八个少妇 | 国产亚洲精品精品国产亚洲综合 | 91xxxxx| 俄罗斯黄色录像 | 欧美粗大猛烈老熟妇 | 免费看特级毛片 | 日韩在线一二三区 | 俺去俺来也在线www色官网 | 国产波霸爆乳一区二区 | 狠狠爱免费视频 | 亚洲黄av| 欧美另类视频在线 | 日韩国产欧美在线观看 | 91久久视频| 国产精品爽 | 在线观看视频福利 | 欧美破处女 | 催眠调教艳妇成肉便小说 | 日韩成人性视频 | 一区二区三区 中文字幕 | 成人三级电影网站 | 性欧美色图 | 无码人妻aⅴ一区二区三区玉蒲团 | 337p亚洲欧洲色噜噜噜 | 香蕉茄子视频 | 精品无码国产污污污在线观看 | 进去里在线观看 | 麻豆网站免费看 | www.天天射 | 中文字幕二| 91精品国产91| 日韩3区 | 天堂久久网 | 申鹤乳液狂飙 | 午夜视频在线观看国产 | 精品久久国产视频 | 久久精品欧美一区 | 久久国产精品99久久人人澡 | 一级片在线观看免费 | 美女100%视频免费观看 | 中国在线观看片免费 | 日韩欧美国产高清 | 欧美日韩中出 | 国产欧美日韩另类 | 欧美日韩国产在线播放 | 色呦呦在线播放 | caopeng在线视频 | 久久国产成人精品国产成人亚洲 | 国产激情自拍 | 国产精品腿扒开做爽爽爽挤奶网站 | 色综合视频在线 | 久久久成人免费 | 最新免费av| 中文字幕二区在线观看 | 一区二区中文字幕 | 国产成人看片 | 中文字幕久久久久久久 | 日本少妇毛茸茸 | 欧美精品卡一卡二 | 日韩欧美一区二区在线 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | 二男一女一级一片 | 天天精品视频 | 粉嫩精品久久99综合一区 | jizz美女| 日韩欧美在线观看一区二区三区 | 午夜婷婷色| 亚洲欧美一二三 |