count的几种写法
孔乙己顯出極高興的樣子,將兩個指頭的長指甲敲著柜臺,點頭說,“對呀對呀!……回字有四樣寫法,你知道么?”我愈不耐煩了,努著嘴走遠。孔乙己剛用指甲蘸了酒,想在柜上寫字,見我毫不熱心,便又嘆一口氣,顯出極惋惜的樣子。
寫下這個標題,立刻就聯想到了孔乙己,于是找出了上文的引用。閑話不表,說正事。
count查詢一般在統計滿足某條件的數據總數時會用到,常見的就是數據統計分析和分頁查詢的場景。
這篇文章的目的主要是想研究一下count的用法,找到使用這個方法的最佳實踐。
實現
查詢引擎差異
總所周知,mysql是基于多種存儲引擎的數據庫,不同的存儲引擎之間實現差異很大,在myisam引擎下,將總行數直接保存了下來,而innodb沒有這樣做。
之所以innodb不保存也很好理解,innodb有事務隔離,在不同的事務內,統計到的數據行數是可能存在差異的。
估算方法
統計行數的方法其實并不止這一種,show table status語句也能夠查詢到每張表的數據行數,差別在于,count方法得到的是精確值,而使用這種方法拿到的是一個估算的值,在官方文檔的描述中提到,這種估算方法計算出來的值誤差能達到50%,所以如果日常使用,只能提供對數據量級上的估算,在單表數據量大的時候也許有點用、
那么他又是怎么實現的呢?
數據庫中存在描述表信息的元數據,mysql存放元數據的庫叫information_schema,這個庫下的TABLES表里有個字段叫TABLE_ROWS,用這個字段來保存估算的數據行數。
select TABLE_ROWS from information_schema.'TABLES' WHERE TABLE_NAME = 'xxxx'使用查詢驗證了一下,兩者的值一致,說明確實是取的這里的值
性能
先說結論,性能上
count(*) = count(1) >= count(primary key) >= count(非空字段) >= count(可空字段)幾種查詢方式各自的實現:
| count(1) | 遍歷整張表,不取值,累加行數 |
| count(primaryKey) | 遍歷整張表,把主鍵值拿出來,累加行數 |
| count(非空字段) | 遍歷整張表,讀出這個字段,累加 |
| count(可空字段) | 遍歷整張表,讀出這個字段,判斷不為空后累加 |
| count(*) | 遍歷整張表,數據庫層面進行了優化,不會把字段全部取出來,按行累加 |
阿里的java開發手冊上將count(*)作為推薦用法,書里給出的理由:
【強制】不要使用 count(列名)或 count(常量)來替代 count(),count()是 SQL92 定義的標
準統計行數的語法,跟數據庫無關,跟 NULL 和非 NULL 無關。
驗證
雖然根據資料得出了關于性能差異的結論,但是還是想自己找張表驗證一下結論。
找了張6w數據的表嘗試使用不同的count語句進行查詢,發現性能差異并不明顯,也許是數據量太小,反正在我的測試下幾乎沒有差異。
參考資料
https://segmentfault.com/a/1190000022262561
https://juejin.cn/post/6844903974445776903
https://www.zhihu.com/question/34781415
https://www.modb.pro/db/48242
總結
以上是生活随笔為你收集整理的count的几种写法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 正版破解软件下载站大全(转载
- 下一篇: gtasa手机版android7.1,圣