电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

淺談MySQL 統計行數的 count

瀏覽:5日期: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 數據庫
相關文章:
主站蜘蛛池模板: Brotu | 关注AI,Web3.0,VR/AR,GPT,元宇宙区块链数字产业 | 兰州UPS电源,兰州山特UPS-兰州万胜商贸 | 齿轮减速机_齿轮减速电机-VEMT蜗轮蜗杆减速机马达生产厂家瓦玛特传动瑞环机电 | 盘扣式脚手架-附着式升降脚手架-移动脚手架,专ye承包服务商 - 苏州安踏脚手架工程有限公司 | 土壤肥料养分速测仪_测土配方施肥仪_土壤养分检测仪-杭州鸣辉科技有限公司 | 尊享蟹太太美味,大闸蟹礼卡|礼券|礼盒在线预订-蟹太太官网 | 座椅式升降机_无障碍升降平台_残疾人升降平台-南京明顺机械设备有限公司 | 防腐木批发价格_深圳_惠州_东莞防腐木厂家_森源(深圳)防腐木有限公司 | 软启动器-上海能曼电气有限公司| 不锈钢监控杆_监控立杆厂家-廊坊耀星光电科技有限公司 | 翻斗式矿车|固定式矿车|曲轨侧卸式矿车|梭式矿车|矿车配件-山东卓力矿车生产厂家 | 地埋式垃圾站厂家【佳星环保】小区压缩垃圾中转站转运站 | 电动葫芦|手拉葫芦|环链电动葫芦|微型电动葫芦-北京市凌鹰起重机械有限公司 | 山东臭氧发生器,臭氧发生器厂家-山东瑞华环保设备 | 钛合金标准件-钛合金螺丝-钛管件-钛合金棒-钛合金板-钛合金锻件-宝鸡远航钛业有限公司 | 螺旋绞龙叶片,螺旋输送机厂家,山东螺旋输送机-淄博长江机械制造有限公司 | 东莞螺杆空压机_永磁变频空压机_节能空压机_空压机工厂批发_深圳螺杆空压机_广州螺杆空压机_东莞空压机_空压机批发_东莞空压机工厂批发_东莞市文颖设备科技有限公司 | 山东商品混凝土搅拌楼-环保型搅拌站-拌合站-分体仓-搅拌机厂家-天宇 | 北京遮阳网-防尘盖土网-盖土草坪-迷彩网-防尘网生产厂家-京兴科技 | 施工电梯_齿条货梯_烟囱电梯_物料提升机-河南大诚机械制造有限公司 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | 山东聚盛新型材料有限公司-纳米防腐隔热彩铝板和纳米防腐隔热板以及钛锡板、PVDF氟膜板供应商 | 档案密集架,移动密集架,手摇式密集架,吉林档案密集架-厂家直销★价格公道★质量保证 | 【连江县榕彩涂料有限公司】官方网站| 湖南教师资格网-湖南教师资格证考试网| 珠光砂保温板-一体化保温板-有釉面发泡陶瓷保温板-杭州一体化建筑材料 | 气动隔膜泵-电动隔膜泵-循环热水泵-液下排污/螺杆/管道/化工泵「厂家」浙江绿邦 | 【直乐】河北石家庄脊柱侧弯医院_治疗椎间盘突出哪家医院好_骨科脊柱外科专业医院_治疗抽动症/关节病骨伤权威医院|排行-直乐矫形中医医院 | 压滤机-洗沙泥浆处理-压泥机-山东创新华一环境工程有限公司 | 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 - 杭州标识标牌|文化墙|展厅|导视|户内外广告|发光字|灯箱|铭阳制作公司 | 齿辊分级破碎机,高低压压球机,立式双动力磨粉机-郑州长城冶金设备有限公司 | 生物颗粒燃烧机-生物质燃烧机-热风炉-生物颗粒蒸汽发生器-丽水市久凯能源设备有限公司 | 洗瓶机厂家-酒瓶玻璃瓶冲瓶机-瓶子烘干机-封口旋盖压盖打塞机_青州惠联灌装机械 | 工业设计,人工智能,体验式3D展示的智能技术交流服务平台-纳金网 J.S.Bach 圣巴赫_高端背景音乐系统_官网 | 土壤检测仪器_行星式球磨仪_土壤团粒分析仪厂家_山东莱恩德智能科技有限公司 | 拼装地板,悬浮地板厂家,悬浮式拼装运动地板-石家庄博超地板科技有限公司 | 武汉不干胶印刷_标签设计印刷_不干胶标签印刷厂 - 武汉不干胶标签印刷厂家 | 安德建奇火花机-阿奇夏米尔慢走丝|高维|发那科-北京杰森柏汇 | 热闷罐-高温罐-钢渣热闷罐-山东鑫泰鑫智能热闷罐厂家 | 风电变桨伺服驱动器-风电偏航变桨系统-深圳众城卓越科技有限公司 | 吹塑加工_大型吹塑加工_滚塑代加工-莱力奇吹塑加工有限公司 |