日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

淺談MySQL 統計行數的 count

瀏覽:50日期:2023-10-14 07:45:04

MySQL count() 函數我們并不陌生,用來統計每張表的行數。但如果你的表越來越大,且是 InnoDB 引擎的話,會發現計算的速度會越來越慢。在這篇文章里,會先介紹 count() 實現的原理及原因,然后是 count 不同用法的性能分析,最后給出需要頻繁改變并需要統計表行數的解決方案。

Count() 的實現

InnoDB 和 MyISAM 是 MySQL 常用的數據引擎,由于兩者實現的不同,導致 count() 操作計算的效率也不同。

對于 MyISAM 來說,它把每個表的總行數都存在了磁盤上,因此使用 count(*) 計算時,效率很高直接返回結果。但如果加入了 where 條件,依然會進行搜索,所以效率是不高的。

對于 InnoDB 來說,在進行 count(*) 運算時,會把數據從引擎中一行行讀出來,然后累計計數,自然表大了之后,效率就變低了。

那么,為什么 InnoDB 不能像 MyISAM 在表中記錄呢?原因就在于 InnoDB 比 MyISAM 多了支持事務的特性,同時也需要一定的取舍。由于 MVCC 的控制,使得 MySQL 具有并發的能力,也就是說對于同一時刻,InnoDB 返回的表的行數是不一定的,事務看到的行數與開啟后的一致性視圖有關,換句話說,每個事務能看到的數據版本是不一樣的,只能一行行拿出來進行判斷。

像下面的事務,假設表 t 有 10000 條數據:

Session A Session B Session C select count(*) from t; insert into t (); begin; insert into t(); select count(*) from t; select count(*) from t; select count(*) from t; 10000; 結果是 10002 結果是 10001

對于 Session A 來說,Session B 未提交不可見,Session C 提交了,但是在 Session A 啟動后提交的,也不可見。所以是 10000.

而對于 Session B 而言,Session C 在啟動之前提交,自己又插入了一條,所以結果是 10002.

其實 InnoDB 在進行 count(*) 操作時,還是做了優化的,在進行 count(*) 操作時,由于普通索引會保存主鍵的 id 值,所以會找到最小的那顆普通索引樹進行查找,而不是去遍歷主鍵索引樹。

在保證邏輯正確的前提下,減少掃描的數據量,是數據庫系統設計的通用法則。

另外在使用 show table status 時,也可以查詢出行數,而且速度很快,但需要注意的是,該命令是通過索引統計的值來采樣估算的。官方文檔說誤差可以有 40%-50%.

但如果我們真的需要實時的獲取的某個表的行數,應該怎么辦呢?

手動保存表的數量

用緩存系統來保存計數

對于進行更新的表,可能會想到用緩存系統來支持。比如 Redis 里來保存某個表總行數。

每次插入數據庫時,Redis 計數加一,相反則減一,這樣看起來讀寫操作都很快,但會存在一些問題。

緩存系統會丟失更新:

對于 Redis 在內存中的數據,需要定期的同步到磁盤中,但對于 Redis 異常重啟,就沒有辦法了。比如在 Redis 中插入后,Redis 重啟,數據沒有持久化到硬盤。這時可以在重啟 Redis 后,從數據庫執行下 count(*) 操作,然后更新到 Redis 中。一次全表掃描還是可行的。

邏輯不精確:

假設一個頁面中,需要顯示一張表的行數,以及每一條數據。在實現時,可以先從 Redis 取數量,然后從數據庫里取記錄。

但可能會出現這樣的情況:

數據庫查到 100 行結果里有最新插入的記錄,而 Redis 計數里少 1. 數據庫查到 100 行結果沒有最新的記錄,但 Redis 計數卻多了 1. Session A Session B 插入一條數據; T1 讀 Redis 計數; T2 從數據庫中查記錄; Redis 計數加 1; T3

對于 Session B 來說,在 T2 時刻,會發現 Redis 的數量比數據庫少 1 條。

Session A Session B Redis 計數加 1; T1 讀 Redis 計數; T2 從數據庫中查記錄; 插入一條數據; T3

對于 Session B 來說,在 T2 時刻,會發現 Redis 的數量比數據庫多 1 條。

其實產生問題的原因就是因為 Redis 和數據庫查記錄沒有在同一個事務中。

用數據庫保存

由于 InnoDB 引擎的支持,MySQL 本身是支持事務的,所以將 Redis 的插入操作換成在數據庫的更新操作,就可以利用在RR級別下的事務特性,進而保證數據的精確性。

而且還有一點,由于 redo log 的支持,在 MySQL 發生異常時,是可以保證 crash-safe。

不同 count 用法的執行效率

count() 本身是一個聚合函數,對于返回的結果集,一行行地判斷。如果參數不是 NULL 的話,會一直累加,最后返回結果。

所以 count(*), count(id), count(1) 表示都是返回滿足條件的結果集總行數。

而 count(字段),則表示滿足條件的數據行里,不為 NULL 的字段。

對于 count(id) 來說,InnoDB 會遍歷整張表,把每行 id 取出來,給 server 層。Server 判斷 id 是否為空,然后累加。

對于 count(1) 來說,InnoDB 會遍歷整張表,但不取值。Server 層會自己放入 1,然后累加。

所以對于 count(1) 的執行會比 count(*) 要快,少了解析數據行以及拷貝字段值的操作。

對于 count(字段) 來說,如果字段定義時是 not null, 會一行行讀出,并判斷不能為 null,然后累加。如果定義時可以為 null,執行時,需要將值去除,判斷不是 null 才累加。

count(*) 除外,專門做了優化,不取值,直接按行累加,并且會找到最小的索引樹進行計算。

總結

MySQL count() 函數的執行效率和底層的數據引擎有關。MyISAM 不加 where 條件,查詢會很快,但不支持事務。InnoDB 支持事務,由于 MVCC 的實現,導致每次查詢都需要一行行的掃描,效率不高。

解決方法可以通過設計外部緩存如 Redis,保存記錄。但存在異常重啟和數據不準確的情況。可以通過在 InnoDB 中新建一張表,保存記錄這樣的解決方案。

最后,InnoDB 對 count(*) 做了獨立的優化,而其他的 count 操作,則需要額外的操作。

以上就是淺談MySQL 統計行數的 count的詳細內容,更多關于Mysql count的資料請關注好吧啦網其它相關文章!

標簽: MySQL 數據庫
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品久久久久久久久久10秀| 99久久99久久精品国产片果冰| 麻豆精品在线| 蜜桃视频第一区免费观看| 视频一区中文字幕精品 | 日韩亚洲在线| 国精品产品一区| 你懂的国产精品永久在线| 99成人在线| 国产成人a视频高清在线观看| 黄色亚洲精品| 亚洲综合日韩| 欧美日韩国产高清电影| 四虎884aa成人精品最新| 久久一区二区三区喷水| 精品在线99| 日韩中文字幕一区二区高清99| 日韩精选在线| 精品国产a一区二区三区v免费| 激情欧美亚洲| 国产黄色一区| 亚洲一区二区三区免费在线观看| 国产欧美日韩| 激情91久久| 精品国产欧美| 亚洲精品观看| 国产综合精品一区| 麻豆免费精品视频| 视频精品一区二区| 日本免费一区二区三区四区| 日韩高清成人在线| 亚洲黄色影院| 美女高潮久久久| 蜜臀av性久久久久蜜臀aⅴ流畅| 久久久久久网| 国产精品网址| 亚洲欧美在线专区| 99视频一区| 亚洲二区视频| 国产中文在线播放| 久久天堂影院| 国产精品亚洲欧美| 国产精品夜夜夜| 国产乱码精品一区二区三区四区 | 国产精品白丝av嫩草影院| 石原莉奈在线亚洲二区| 久久中文字幕av一区二区不卡| 麻豆精品少妇| 国产精品22p| 国产精品久久久久av蜜臀| 日韩国产在线观看一区| 中文字幕日韩亚洲| 男人操女人的视频在线观看欧美| 亚州av乱码久久精品蜜桃| 亚洲香蕉网站| 欧美福利在线| 伊人精品在线| 亚洲一区二区小说| 中文字幕一区二区三区日韩精品| 一区二区亚洲视频| 日韩av网站在线免费观看| 日韩在线成人| 欧美精品国产白浆久久久久| 怡红院精品视频在线观看极品| 午夜精品一区二区三区国产| 久久男人天堂| 日韩中文影院| 欧洲av一区二区| 激情婷婷亚洲| 亚洲视频国产精品| 国产毛片精品| 成人久久一区| 视频在线观看91| 日韩av字幕| 国产99在线| 日韩av网站在线观看| 在线日韩av| 99视频一区| 欧美视频久久| 色爱综合网欧美| 在线视频精品| 欧美日韩精品一区二区三区在线观看| 国产欧美一级| 久久婷婷av| 日韩欧美2区| 日韩一区电影| 一区二区高清| 精品久久97| 国产在线日韩| 日韩欧美中文在线观看| 日韩成人综合| 伊人久久一区| 136国产福利精品导航网址| 午夜亚洲福利| 欧美午夜精彩| 麻豆国产精品| 香蕉成人久久| 国产精品久久久久av电视剧| 日韩美女精品| 国产一区导航| 久久精品不卡| 国产一区日韩| 欧美久久精品| 综合激情在线| 国产免费成人| 99久久精品费精品国产| 日本aⅴ亚洲精品中文乱码 | 亚洲黄色在线| 日本少妇一区| av在线资源| 亚洲最新无码中文字幕久久 | 久久精品卡一| 91视频久久| 国产一区二区久久久久| 欧美日韩视频免费看| 欧美日韩精品免费观看视频完整| 日韩深夜视频| 中文字幕一区久| 国产一区福利| 成人三级高清视频在线看| 国产高清视频一区二区| 麻豆精品国产91久久久久久| 国产精品tv| 精品国产亚洲一区二区在线观看| 国产精品1luya在线播放| 美女视频网站久久| 国产一区二区三区91| 六月婷婷综合| 国产99亚洲| 国产精品日本| 一区福利视频| 亚洲综合中文| 久久超碰99| 色在线中文字幕| 五月天久久777| 色综合视频一区二区三区日韩| 亚洲久久在线| 国产亚洲一区| 国产精品成人a在线观看| 欧洲一级精品| 亚洲精品日本| 久久精品福利| 国产精品91一区二区三区| 蜜桃av一区二区在线观看| 久久精品72免费观看| 久草精品视频| 亚洲精品极品少妇16p| 88久久精品| 99国产精品免费视频观看| 亚洲精品乱码| 久久久久国产精品一区二区| 一二三区精品| 色婷婷精品视频| 日本成人在线不卡视频| 午夜天堂精品久久久久| 成人欧美一区二区三区的电影| 免费在线欧美视频| 久久久久免费| 日韩中文字幕视频网| 亚洲天堂1区| 日本强好片久久久久久aaa| 中文在线а√在线8| 日韩高清在线一区| 久久三级福利| 精品黄色一级片| 亚洲bt欧美bt精品777| 欧美日韩一区二区综合| 欧美激情三区| 久久精品99国产精品日本| 99亚洲视频| 国内激情久久| 久久九九精品| 国产精品蜜芽在线观看| 国产福利亚洲| 欧美久久精品| 综合日韩在线| 国产色综合网| 伊人久久成人| 亚洲激情中文| 精品中文一区| 亚洲作爱视频| 黄色免费成人| 久久夜色精品| 奶水喷射视频一区| 尤物精品在线| 免费精品视频最新在线| 国产精品欧美在线观看| 国产精品日韩精品在线播放| 久久国产麻豆精品| 国产经典一区| 久久精品色播| 极品av在线| 欧美在线观看视频一区| 亚洲性色av| 在线午夜精品| 日本aⅴ精品一区二区三区| 国产日韩1区| 日韩成人a**站| 欧美日韩黑人| 日韩欧美美女在线观看|