精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

為什么MySQL的count()方法這么慢?

數據庫 MySQL
mysql用count方法查全表數據,在不同的存儲引擎里實現不同,myisam有專門字段記錄全表的行數,直接讀這個字段就好了。而innodb則需要一行行去算。

兄弟們。

淺淺的炫個富吧。

說出來你們可能不信。

手機你們有嗎?我有。

短信,知道吧?一條一毛錢,我天天發。

你敢想嗎?

所以說,年輕人,有錢是真的好。

今天,我們就以短信為話題聊起。

短信,它又叫SMS。

比如說,你有一張短信表(sms),里面放了各種需要發送的短信信息。

圖片

sms建表sql

圖片

sms表

需要注意的是state字段,為0的時候說明這時候短信還未發送。

此時還會有一個異步線程不斷的撈起未發送(state=0)的短信數據,執行發短信操作,發送成功之后state字段會被置為1(已發送)。也就是說未發送的數據會不斷變少。

圖片

異步線程發送短信

假設由于某些原因,你現在需要做一些監控,比如監控的內容是,你的sms數據表里還有沒有state=0(未發送)的短信,方便判斷一下堆積的未發送短信大概在什么樣的一個量級。

為了獲取滿足某些條件的行數是多少,我們一般會使用count()方法。

這時候為了獲取未發送的短信數據,我們很自然就想到了使用下面的sql語句進行查詢。

select count(*) from sms where state = 0;

然后再把獲得數據作為打點發給監控服務。

當數據表小的時候,這是沒問題的,但當數據量大的時候,比如未發送的短信到了百萬量級的時候,你就會發現,上面的sql查詢時間會變得很長,最后timeout報錯,查不出結果了。

為什么?

我們先從count()方法的原理聊起。

count()的原理

count()方法的目的是計算當前sql語句查詢得到的非NULL的行數。

我們知道mysql是分為server層和存儲引擎層的。

圖片

Mysql架構

存儲引擎層里可以選擇各種引擎進行存儲,最常見的是innodb、myisam。具體使用哪個存儲引擎,可以通過建表sql里的ENGINE?字段進行指定。比如這篇文章開頭的建表sql里用了ENGINE=InnoDB,那這張表用的就是innodb引擎。

雖然在server層都叫count()方法,但在不同的存儲引擎下,它們的實現方式是有區別的。

比如同樣是讀全表數據  select count(*) from sms;語句。

使用 myisam引擎的數據表里有個記錄當前表里有幾行數據的字段,直接讀這個字段返回就好了,因此速度快得飛起。

而使用innodb引擎的數據表,則會選擇體積最小的索引樹,然后通過遍歷葉子節點的個數挨個加起來,這樣也能得到全表數據。

因此回到文章開頭的問題里,當數據表行數變大后,單次count就需要掃描大量的數據,因此很可能就會出現超時報錯。

那么問題就來了。

為什么innodb不能像myisam那樣實現count()方法

myisam和innodb這兩個引擎,有幾個比較明顯的區別,這個是八股文常考了。

其中最大的區別在于myisam不支持事務,而innodb支持事務。

而事務,有四層隔離級別,其中默認隔離級別就是可重復讀隔離級別(RR)。

圖片

四層隔離級別

innodb引擎通過MVCC實現了可重復隔離級別,事務開啟后,多次執行同樣的select快照讀,要能讀到同樣的數據。

于是我們看個例子。

圖片

為什么innodb不單獨記錄表行數

對于兩個事務A和B,一開始sms表假設就2條數據,那事務A一開始確實是讀到2條數據。事務B在這期間插入了1條數據,按道理數據庫其實有3條數據了,但由于可重復讀的隔離級別,事務A依然還是只能讀到2條數據。

因此由于事務隔離級別的存在,不同的事務在同一時間下,看到的表內數據行數是不一致的,因此innodb,沒辦法,也沒必要像myisam那樣單純的加個count字段信息在數據表上。

那如果不可避免要使用count(),有沒有辦法讓它快一點?

各種count()方法的原理

count()的括號里,可以放各種奇奇怪怪的東西,想必大家應該看過,比如放個星號*,放個1,放個索引列啥的。

我們來分析下他們的執行流程。

count方法的大原則是server層會從innodb存儲引擎里讀來一行行數據,并且只累計非null的值。但這個過程,根據count()方法括號內的傳參,有略有不同。

count(*)

server層拿到innodb返回的行數據,不對里面的行數據做任何解析和判斷,默認取出的值肯定都不是null,直接行數+1。

count(1)

server層拿到innodb返回的行數據,每行放個1進去,默認不可能為null,直接行數+1.

count(某個列字段)

由于指明了要count某個字段,innodb在取數據的時候,會把這個字段解析出來返回給server層,所以會比count(1)和count(*)多了個解析字段出來的流程。

如果這個列字段是主鍵id,主鍵是不可能為null的,所以server層也不用判斷是否為null,innodb每返回一行,行數結果就+1.

如果這個列是普通索引字段,innodb一般會走普通索引,每返回一行數據,server層就會判斷這個字段是否為null,不是null的情況下+1。當然如果建表sql里字段定義為not null的話,那就不用做這一步判斷直接+1。

如果這個列沒有加過索引,那innodb可能會全表掃描,返回的每一行數據,server層都會判斷這個字段是否為null,不是null的情況下+1。同上面的情況一樣,字段加了not null也就省下這一步判斷了。

理解了原理后我們大概可以知道他們的性能排序是

count(*)count(1) > count(主鍵id) > count(普通索引列) > count(未加索引列)

所以說count(*),已經是最快的了。

知道真相的我眼淚掉下來。?

那有沒有其他更好的辦法?

允許粗略估計行數的場景

我們回過頭來細品下文章開頭的需求,我們只是希望知道數據庫里還有多少短信是堆積在那沒發的,具體是1k還是2k其實都是差不多量級,等到了百萬以上,具體數值已經不重要了,我們知道它現在堆積得很離譜,就夠了。因此這個場景,其實是允許使用比較粗略的估計的。

那怎么樣才能獲得粗略的數值呢?

還記得我們平時為了查看sql執行計劃用的explain命令不。

其中有個rows,會用來估計接下來執行這條sql需要掃描和檢查多少行。它是通過采樣的方式計算出來的,雖然會有一定的偏差,但它能反映一定的數量級。

圖片

explain里的rows

有些語言的orm里可能沒有專門的explain語法,但是肯定有執行raw sql的功能,你可以把explain語句當做raw sql傳入,從返回的結果里將rows那一列讀出來使用。

一般情況下,explain的sql如果能走索引,那會比不走索引的情況更準 。單個字段的索引會比多個字段組成的復合索引要準。索引區分度越高,rows的值也會越準。

這種情況幾乎滿足大部分的監控場景。但總有一些場景,它要求必須得到精確的行數,這種情況該怎么辦呢?

必須精確估計行數的場景

這種場景就比較頭疼了,但也不是不能做。

我們可以單獨拉一張新的數據庫表,只為保存各種場景下的count。

CREATE TABLE `count_table` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`cnt_what` char(20) NOT NULL DEFAULT '' COMMENT '各種需要計算的指標',
`cnt` tinyint NOT NULL COMMENT 'cnt指標值',
PRIMARY KEY (`id`),
KEY `idx_cnt_what` (`cnt_what`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

圖片

count_table表保存各種場景下的count

當需要獲取某個場景下的cout值時,可以使用下面的sql進行直接讀取,快得飛起。

select cnt from count_table where cnt_what = "未發送的短信數量"; 

那這些count的結果值從哪來呢?

這里分成兩種情況。

實時性要求較高的場景

如果你對這個cnt計算結果的實時性要求很高,那你需要將更新cnt的sql加入到對應變更行數的事務中。

比如我們有兩個事務A和B,分別是增加未發送短信和減少未發送短信。

圖片

將更改表行數的操作放入到事務里

這樣做的好處是事務內的cnt行數依然符合隔離級別,事務回滾的時候,cnt的值也會跟著回滾。

壞處也比較明顯,多個線程對同一個cnt進行寫操作,會觸發悲觀鎖,多個線程之間需要互相等待。對于高頻寫的場景,性能會有折損。

實時性沒那么高的場景

如果實時性要求不高的話,比如可以一天一次,那你可以通過全表掃描后做計算。

舉個例子,比如上面的短信表,可以按id排序,每次取出1w條數據,記下這一批里最大的id,然后下次從最大id開始再拿1w條數據出來,不斷循環。

對于未發送的短信,就只需要在撈出的那1w條數據里,篩選出state=0的條數。

圖片

batch分批獲取短信表

當然如果有條件,這種場景最好的方式還是消費binlog將數據導入到hive里,然后在hive里做查詢,不少公司也已經有現成的組件可以做這種事情,不用自己寫腳本,豈不美哉。

圖片

mysql同步hive

總結

mysql用count方法查全表數據,在不同的存儲引擎里實現不同,myisam有專門字段記錄全表的行數,直接讀這個字段就好了。而innodb則需要一行行去算。

性能方面 count(*) ≈ count(1) > count(主鍵id) > count(普通索引列) > count(未加索引列),但哪怕是性能最好的count(*),由于實現上就需要一行行去算,所以數據量大的時候就是不給力。

如果確實需要獲取行數,且可以接受不那么精確的行數(只需要判斷大概的量級)的話,那可以用explain里的rows,這可以滿足大部分的監控場景,實現簡單。

如果要求行數準確,可以建個新表,里面專門放表行數的信息。

如果對實時性要求比較高的話,可以將更新行數的sql放入到對應事務里,這樣既能滿足事務隔離性,還能快速讀取到行數信息。

如果對實時性要求不高,接受一小時或者一天的更新頻率,那既可以自己寫腳本遍歷全表后更新行數信息。也可以將通過監聽binlog將數據導入hive,需要數據時直接通過hive計算得出。

參考資料

《丁奇mysql45講》

責任編輯:武曉燕 來源: 小白debug
相關推薦

2018-08-16 08:03:21

Python語言解釋器

2016-12-28 11:28:19

.NET反射

2020-08-14 09:11:29

RedisQPS數據庫

2021-05-29 06:23:47

webpack esbuild

2025-06-20 04:55:00

Wi-Fi組網CSSR

2015-09-09 11:04:28

Wi-Fi網速

2018-10-28 15:40:23

Python編程語言

2025-03-04 07:30:00

開發前端Node.js

2024-02-26 21:15:20

Kafka緩存參數

2020-02-27 15:44:41

Nginx服務器反向代理

2022-06-02 08:03:19

PyCharmPython代碼

2019-08-30 14:58:47

JavaScript程序員編程語言

2013-03-04 10:10:36

WebKit瀏覽器

2022-06-13 21:52:02

CDN網絡節點

2020-02-27 21:03:30

調度器架構效率

2012-08-17 10:01:07

云計算

2020-03-30 15:05:46

Kafka消息數據

2020-06-16 14:13:50

Kubernetes容器Linux

2024-03-07 10:21:56

2022-05-30 10:23:59

HTTPHTTP 1.1TCP
點贊
收藏

51CTO技術棧公眾號

久久久久久亚洲综合影院红桃| 日韩美女精品| 亚洲一区二区三区中文字幕在线| 成人黄色片视频网站| 超碰中文字幕在线| 欧美精品一区二区三区精品| 日韩美女视频一区二区在线观看| 欧美在线观看www| 在线看黄色av| 国产91丝袜在线播放| 日本久久久久久| 国产天堂av在线| 久久av电影| 日韩色视频在线观看| 亚洲熟妇av一区二区三区| 黄色片网站在线| 91论坛在线播放| 91九色蝌蚪嫩草| 日韩久久中文字幕| 欧美精选在线| 爽爽爽爽爽爽爽成人免费观看| 免费观看污网站| 久久91视频| 欧美日韩在线视频一区二区| 日韩精品一区二区三区电影| 韩日在线视频| www.欧美色图| 99国产在线视频| 艳妇乳肉豪妇荡乳av| 国产农村妇女精品一区二区| 久久成人亚洲精品| 国产7777777| 一区二区三区视频免费观看| 欧美成人精精品一区二区频| 亚洲图色中文字幕| 欧美日韩不卡| 欧美性猛交xxxx富婆| 日韩a级在线观看| av理论在线观看| 综合久久久久久久| 五月天丁香综合久久国产| 视频一区二区在线播放| 成人精品一区二区三区四区| 91精品在线观| 国产又粗又猛又爽| 蜜臀av在线播放一区二区三区| 日韩免费在线免费观看| 日韩久久中文字幕| 一区二区三区国产在线| 久久久久久尹人网香蕉| 欧美精品一区二区蜜桃| 欧美在线观看天堂一区二区三区| 日韩在线视频二区| 战狼4完整免费观看在线播放版| 九九精品久久| 亚洲天堂久久av| 免费在线观看污| 你懂的视频欧美| 亚洲片在线资源| 亚洲精品91在线| 久久国产电影| 久久精品久久精品亚洲人| 亚洲精品自拍视频在线观看| 波多野结衣在线播放一区| 在线成人激情视频| 国产7777777| 久久久久国产| 欧美激情亚洲综合一区| 亚洲一区欧美在线| 麻豆91精品| 国产精品扒开腿做爽爽爽视频 | 一本大道av伊人久久综合| 在线免费观看视频一区| 黄页网站在线观看视频| 六月婷婷中文字幕| 午夜一区二区视频| 中文字幕在线观看视频网站| 国产精品呻吟| 国产精品久久色| 欧美人成在线观看| 巨骚激情综合| 国产精品成人一区二区艾草| 2021狠狠干| 日本在线视频中文有码| 天天影视色香欲综合网老头| 激情综合网婷婷| 国产成人精品一区二区三区在线 | h狠狠躁死你h高h| 成人黄色av电影| 视频一区二区在线观看| 国产精品一区二区三区视频网站| 亚洲国产美女搞黄色| 国产无套粉嫩白浆内谢的出处| 欧美特黄色片| 亚洲国产精品va在线| 黄色片网站免费| 你懂的国产精品| 欧美自拍大量在线观看| 一级视频在线播放| 成人av在线一区二区| 农村寡妇一区二区三区| 高潮毛片在线观看| 狠狠躁夜夜躁久久躁别揉| 久久这里只精品| 高潮按摩久久久久久av免费| 中文字幕精品在线视频| 劲爆欧美第一页| 日韩黄色片在线观看| 亚洲直播在线一区| 国产在线资源| 亚洲国产中文字幕| 亚洲欧洲日本精品| 久久亚洲道色| 久久精品最新地址| 天天爽夜夜爽人人爽| 国产成人啪免费观看软件| 青青草久久网络| 不卡av免费观看| 欧美高清性hdvideosex| 欧美色图亚洲激情| 国产一区久久| 91免费视频国产| 国家队第一季免费高清在线观看| 亚洲国产一区二区视频| 91蝌蚪视频在线| 成人三级视频| 国产91色在线|免| 五月婷婷六月丁香| 亚洲一区二区三区在线| 亚洲欧美手机在线| 日韩黄色大片| 日韩免费观看高清| 欧美理论在线观看| 亚洲成人你懂的| 人妻互换一二三区激情视频| 香蕉视频国产精品| 国产精品手机播放| 国产三级电影在线观看| 日韩欧美999| 99久久免费看精品国产一区| 国产精品大片| 91传媒在线免费观看| 1769在线观看| 欧美日韩中字一区| 亚洲自拍偷拍图| 日韩精品欧美成人高清一区二区| 鲁片一区二区三区| 亚洲福利影院| 亚洲毛茸茸少妇高潮呻吟| 日韩xxx高潮hd| 不卡视频免费播放| 国产午夜大地久久| 青青草原在线亚洲| 91国内免费在线视频| 少妇人妻一区二区| 天天色综合成人网| 欧美激情aaa| 日韩成人一区二区| 亚洲精品日韩在线观看| 欧美激情不卡| 久久艹在线视频| 农村少妇久久久久久久| 亚洲成a人片在线不卡一二三区| 亚洲色偷偷色噜噜狠狠99网| 国产日韩欧美三级| 欧美高清性xxxxhd| jizz亚洲女人高潮大叫| 色偷偷偷亚洲综合网另类| 国产深喉视频一区二区| 成人av色网站| 3d动漫一区二区三区在线观看| 欧美日韩一区二区三区高清| 萌白酱视频在线| 韩国女主播成人在线| 精品无码av无码免费专区| 国内视频在线精品| 国产成人一区二区三区小说| 1pondo在线播放免费| 一本色道久久综合亚洲精品不卡 | 人妻互换一区二区激情偷拍| 久久99久久精品| 欧美做暖暖视频| 免费成人三级| 国产精品久久久久不卡| 免费在线观看黄| 日韩欧美123| 六月丁香激情综合| 国产精品久久久久久久久动漫 | 精品国产18久久久久久二百| 久久久久国产精品一区| 免费a在线观看| 91精品国产欧美一区二区18| 国产成人无码精品久久久久| 国产精品视频九色porn| 日本天堂在线播放| 日本大胆欧美人术艺术动态| 欧美大黑帍在线播放| 国产一区二区三区四区五区| 5566av亚洲| 午夜精品久久久久久久久久蜜桃| 伦伦影院午夜日韩欧美限制| 天堂√在线中文官网在线| 777亚洲妇女| 91美女免费看| 日韩一区欧美小说| 免费中文字幕av| 国产精品一区二区免费不卡| 欧在线一二三四区| 亚洲91中文字幕无线码三区| 欧美1o一11sex性hdhd| 日本免费一区二区视频| 国产精品情侣自拍| 黄色软件视频在线观看| 久久在精品线影院精品国产| 国产在线网站| 亚洲精品国产福利| 性欧美8khd高清极品| 精品视频123区在线观看| 日韩经典在线观看| 亚洲欧美日本在线| 天天操天天舔天天射| 97精品久久久午夜一区二区三区| 亚洲图片 自拍偷拍| 日韩电影在线观看电影| 91专区在线观看| 欧美日韩国产综合网| 日本不卡一区二区三区四区| 欧美伦理影院| 人禽交欧美网站免费| 色婷婷综合久久久久久| 福利视频久久| 久久gogo国模啪啪裸体| 国产欧美一区二区三区在线看| 中文字幕色婷婷在线视频| 久久久久久国产| 中国黄色片一级| 97精品一区| 色噜噜狠狠色综合网| 免费观看不卡av| 久久精品久久精品国产大片| 成人免费直播在线| 99久久国产免费免费| 日韩一区二区三区精品视频第3页| 国产精品偷伦视频免费观看国产| 日韩免费电影| 日本一区二区三区在线播放| 最近在线中文字幕| 欧美亚洲成人精品| 华人av在线| 热草久综合在线| 91精品xxx在线观看| 热久久99这里有精品| 性欧美freesex顶级少妇| 欧美亚洲另类视频| 欧美性suv| 国产精品啪视频| 亚洲免费一区| 4444kk亚洲人成电影在线| 国产精品中文| 电影午夜精品一区二区三区| 66精品视频在线观看| 国产日韩欧美精品| 日韩一级电影| 午夜精品视频在线观看一区二区| 成人在线免费小视频| 性做爰过程免费播放| 欧美区亚洲区| koreanbj精品视频一区| 每日更新成人在线视频| 三级视频中文字幕| 国内精品国产三级国产a久久| 欧美污在线观看| 99精品在线观看视频| 国产综合精品久久久久成人av| 亚洲视频一区在线| 天堂精品视频| 国内精品偷拍| 天堂资源在线亚洲资源| 亚洲国产一区二区三区在线播放| 91黄色在线看| 日韩高清不卡在线| 天堂在线一区二区三区| www.性欧美| 人妻无码一区二区三区免费| 一区二区三区四区蜜桃| 日韩中文字幕在线观看视频| 欧美日韩精品一区二区天天拍小说 | 五十路在线视频| 中日韩午夜理伦电影免费 | 国产九九九视频| 成人av一区二区三区| 国产毛片欧美毛片久久久| 亚洲男人的天堂在线aⅴ视频| 国产精品免费av一区二区| 欧美视频在线一区| 欧美性猛交 xxxx| 在线成人一区二区| 黄网在线免费看| 国产精品国产亚洲伊人久久| 香蕉大人久久国产成人av| 欧美三级电影在线播放| 在线观看日韩| 妓院一钑片免看黄大片| 懂色av一区二区夜夜嗨| 亚洲色图 激情小说| 午夜久久久久久电影| 国产精品久久久久久久久久久久久久久久久久 | 国产免费人做人爱午夜视频| 国产在线不卡一区| 97人妻人人揉人人躁人人| 亚洲电影在线免费观看| 91极品身材尤物theporn| 亚洲欧美一区二区三区情侣bbw| 性国产高清在线观看| 国产精品视频xxx| 西野翔中文久久精品字幕| 久久www视频| 狠狠色丁香九九婷婷综合五月| 欧美做受高潮6| 午夜电影一区二区三区| 亚洲爱情岛论坛永久| 久久精品视频99| 992tv国产精品成人影院| 欧美精彩一区二区三区| 亚洲精品孕妇| 国产精品99精品无码视亚| 亚洲欧洲一区二区三区| www.五月婷婷.com| 亚洲欧美国产高清va在线播| 尤物yw193can在线观看| 91深夜福利视频| 91视频久久| 午夜两性免费视频| 国产欧美一区二区三区沐欲| 波多野结衣视频网站| 亚洲国产成人av在线| 超免费在线视频| 国产在线一区二| 亚洲国产欧美国产综合一区| 日本一区二区免费视频| 一区二区三区美女| 性少妇videosexfreexxx片| 美女福利视频一区| 国产一区二区三区黄网站| 色乱码一区二区三区熟女| 激情六月婷婷综合| 99鲁鲁精品一区二区三区| 欧美日韩不卡一区二区| 黄视频网站在线看| 成人综合网网址| 欧美96在线丨欧| 国产精品入口麻豆| 亚洲成人av电影| 瑟瑟在线观看| 日本午夜人人精品| 日韩精品永久网址| 成人av毛片在线观看| 亚洲视频在线一区| 高潮一区二区三区乱码| 韩国美女主播一区| 香蕉久久夜色精品国产更新时间| 欧美牲交a欧美牲交aⅴ免费真| 国产三级欧美三级日产三级99| 中文天堂在线资源| 麻豆国产精品va在线观看不卡| 亚洲精品a区| 九色在线视频观看| 国产免费久久精品| 国产乱码久久久久| 欧美精品videosex牲欧美| 欧美日韩一区二区三区四区不卡 | 26uuu精品一区二区| 亚洲精品一区二三区| 久久精品视频播放| 成人高潮视频| 美女网站免费观看视频| 亚洲欧美日韩久久| 天天综合天天色| 国产精品日韩专区| 欧美日韩蜜桃| 公侵犯人妻一区二区三区| 欧美精品第一页| 国产三级电影在线播放| 亚洲欧美日韩不卡一区二区三区| 精品一区二区免费视频| 三级黄色在线视频| 中文字幕在线日韩| 精品亚洲免a| 中文字幕国产免费| 亚洲成人免费视| 免费黄色网页在线观看| 国产精品一区二区三区精品| 日本不卡123| 日本中文字幕免费| 色狠狠av一区二区三区香蕉蜜桃| 国产精品巨作av| 亚洲一区二区在线视频观看| 欧美日韩午夜激情| a视频在线播放| 日韩av在线电影观看|