百萬行mysql,count 函式的思考與總結

2021-08-20 18:29:53 字數 2340 閱讀 1907

如果你的需要是統計總行數時,為什麼要使用count(*),而避免使用指定具體的列名?

count()函式裡面的引數是列名的的時候,那麼會計算這個欄位有值項的次數。也就是,該欄位沒有值的項並不會進入計算範圍(就是網上常說的值為null的項不納入統計)

很多地方都有類似表述:

count ( column ) counts all non-null occurences (or should

count ( * ) counts all rows.

這樣的話,你想統計的行數並不準確。更重要的是,還會增加消耗。因為,需要判斷掃瞄所有行才知道值是否有值。

一般是建議以count(欄位名)替代count(*)。實際使用中,我的理解是,你要統計那個列的總數,比如我想統計會員的總數,那麼我可以以uid作為參考,uid是null的都不去掃瞄了

於是查詢就是select count(uid) from members

如果使用count(*),它會計算總行數。不管你字段是否有值都會列入計算範圍。

另外一點:myisam引擎很容易獲得總行數的統計。查詢速度變得更快。因為myisam儲存引擎已經儲存了表的總行數。

應該是每次新增加一行,這個計數器就加1。英文資料是這樣子說的:

on myisam, doing a query that does select count(*) from , is very fast, since myisam keeps the information in the index

也就是說,把錶的總數快取在索引中了。

注意一點:myisam儲存引擎的表,count(*)速度快的也僅僅是不帶where條件的count。這個想想容易理解的,因為你帶了where限制條件,原來所以中快取的表總數能夠直接返回用嗎?不能用。這個查詢引擎也是需要根據where條件去表中掃瞄資料,進行統計返回的。

歸納:實際程式設計中統計總行數是經常用到的。此時使用count(*)多處可見。我很少看到有人使用列名作為引數:count(a)的情況。即使是這樣使用,可能其初衷也是想統計行數。只是不知道這樣所造成的細微差異而錯誤使用了"列名"的形式。

針對innodb表,盡量不執行select count(*)語句,因為innodb表沒有類似myisam那樣的內部計數器來記錄表記錄總量,執行這個操作將會全表掃瞄,速度很慢。所以呢,表的行數越多,掃瞄的時間就越多。當你錶行數還是小數量的時候體會不出速度差距。比如百萬也感覺不出明顯。上千萬就會很明顯速度差別了。

對策:對innob儲存引擎的大表進行select count()統計總數操作,業界都會盡量避免。

如果要查詢innodb儲存引擎的表總數,要怎麼辦?

總結兩種方案:

方案一:通過查詢information_schema庫,它記錄了innodb型別每個表大致的資料行數

方案二(更優):涉及到總數操作,專門維護乙個總數。新註冊乙個會員,總數值加1,需要總數的時候直接拿這個總數,比如分頁時。

方案二的擴充套件性更好,隨著會員表數量增大,水平切分會員表,要獲取使用者總數。可以專門看這張表。

在網上看到有人問自己的innodb儲存引擎的表資料行數到10億了,要進行分頁,count(*)操作很慢怎麼解決。

總數可能是存在記憶體中,這樣分頁計算的時候速度很快。累加操作的時候將記憶體中的值加1。總數這個值要持久化,還是要存到磁碟上的,也就是資料庫中(可以是關係型資料庫,也可以是mongdb這樣的資料庫很適合儲存計數)。把總數放在記憶體中,只是避免頻繁的磁碟i/0操作(運算元據庫就要涉及到磁碟讀寫)。

ps:這種計數器的思想在計算機的很多地方都會用到。比如mysql資料庫他自己的information_schema庫維護每個表的row總數,就是這樣的方式。

我有個疑問:針對innodb儲存引擎,使用count(1)替代count(*)就避免全表掃瞄,速度很快嗎?

orcalce資料庫有專門對count(1)和count(*)的區別。

count(1)其實這個1,並不是表示第乙個字段,而是表示乙個固定值。

count(1),其實就是計算一共有多少符合條件的行。

1並不是表示第乙個字段,而是表示乙個固定值。

其實就可以想成表中有這麼乙個字段,這個字段就是固定值1,count(1),就是計算一共有多少個1.

同理,count(2),也可以,得到的值完全一樣,count('x'),count('y')都是可以的。一樣的理解方式。在你這個語句理都可以使用,返回的值完全是一樣的。就是計數。

count(*),執行時會把星號翻譯成欄位的具體名字,效果也是一樣的,不過多了乙個翻譯的動作,比固定值的方式效率稍微低一些。

count(1)就是不指定具體字段,固定值。

網上找不到原始碼分析出count(1)到底做了什麼。如果參考oracle資料庫的解釋,其實也不見得就能避免全表掃瞄

POI解析百萬行excel的實現

poi 的usermodel api讀取大資料量excel會導致oom,可以使用eventmodel api來處理這種excel.少量的行數excel可以用 xssfworkbook wb new xssfworkbook inputstream xssfsheet sheet wb.getshee...

mysql count聚合函式效能

count count 主鍵id 和 count 1 都表示返回滿足條件的結果集的總行數 而count 字段 則表示返回滿足條件的資料行裡面,引數 字段 不為 null 的總個數。效能差別 server 層要什麼就給什麼 innodb 只給必要的值 現在的優化器只優化了 count 的語義為 取行數...

百萬行級排序演算法比較與研究

老闆最近給了我乙個空間資料壓縮包,壓縮包中包含10個檔案,每乙個檔案中包含id x座標 y座標 元素 一 元素二五種標籤,每個大約包含四百萬條資料。老闆對我提出的要求是以乙個檔案的xy座標為準,找出其他九個檔案中與其最相近的座標,將相近座標的兩個元素複製到標準檔案中。idx y元素一 元素二當時聽到...