14 count 這麼慢,我該怎麼辦?

2021-09-23 20:21:14 字數 2155 閱讀 3652

在不同的mysql引擎中,count(*)有不同的實現方式。

需要注意的是,這兒討論的是沒有過濾條件的count(*),如果加了where條件的話,myisam表也不是這麼快的。

那為什麼innodb不跟myisam一樣,也把數字存起來呢?

因為即使是在同乙個時刻的多個查詢,由於多版本併發控制(mvcc)的原因,innodb表「應該返回多少行」也是不確定的。

當然,mysql對count(*)也是做了優化的。

innodb是索引組織表,主鍵索引樹的葉子節點是資料,而普通索引樹的葉子節點是主鍵值。所以,普通索引樹比主鍵索引樹小很多。對於count(*)這樣的操作,遍歷哪個索引樹得到的結果邏輯上都是一樣的。因此,mysql優化器會找到最小那顆索引樹來遍歷。在保證邏輯正確的前提下,儘量減少掃瞄的資料量,是資料庫系統設計的通用法則之一。

如過通過show table status命令的話,就會發現這個命令輸出的結果裡也有乙個table_rows用於顯示這個表當前有多少行,這個命令執行挺快的,那這個table_rows能代替count(*)嗎?   答案是不能,索引統計的值是通過取樣來估算的,事實上,table_rows就是從這個取樣估算得來的,因此它也很不準確。官方文件說誤差可能達到40%到50%。

總結:

有哪些方法可以計數,以及各自的優缺點:

比如用redis來儲存乙個表的總行數。表插入一行,redis就加1,刪除一行就減1。這種方式讀寫都很快。

但是快取系統可能會丟失更新。

實際上,將計數儲存在快取系統中的方式,還不只是丟失更新的問題,即使redis正常工作,這個值還是邏輯上不精確的。

比如如下兩個圖:

把這個表的總行數直接放到資料庫裡單獨的一張計數表c中,會怎麼樣?

首先,解決了奔潰丟失的問題,innodb是支援奔潰恢復不丟失資料的。

而且還可以解決上面計數不精確的問題。

因為innodb是支援事務的,預設隔離級別是可重複讀,如下:

select count(?) from t、count(*)、count(主鍵id)、count(1)

還是基於innodb引擎.

首先弄清count()的語義。count()是乙個聚合函式,對於返回的結果集,一行行地判斷,如果count函式的引數不是null,累計值就加1,否則不加。最後返回累計值。

所以,count(*)、count(主鍵id)和count(1)都表示返回滿足條件的結果集的總行數;而count(字段),則表示返回滿足條件的資料行裡面,引數「字段」不為null的總個數。

分析效能差別的時候,可以記住這麼幾個原則:

server層要什麼就給什麼;

innodb只給必要的值;

現在的優化器只優化了count(*)的語義為「取行數」,其他「顯而易見」的優化並沒有做。

count(主鍵id),innodb引擎會遍歷整張表,把每一行的id值都取出來,返回給server層,server拿到id後,判斷是不可能為空的,就按行累加。

count(1),innodb引擎遍歷整張表,但不取值。server層對於返回的每一行,放乙個數字「1」進去,判斷是不可能為空的,按行累加。

單看這兩個,count(1)執行要比count(主鍵id)快,因為引擎返回id會涉及到解析資料行,以及拷貝字段值的操作。

count(字段):如果這個「字段」是定義為not null的話,一行行地從記錄裡面讀出這個字段,判斷不能為null,就按行累加;如果這個「字段」定義允許為null,那麼執行的時候,判斷到有可能是null,還要把值取出來再判斷一下,不是null才累加。

count(*),這個比較例外,並不會把所有欄位都取出來,而是專門做了優化,不取值。count(*)肯定不是null,就按行累計。

結論:按照效率排序:count(字段)

count 這麼慢,我該怎麼辦?

count 統計原理 innodb 是索引組織表,主鍵索引樹的葉子節點是資料,而普通索引樹的葉子節點是主鍵值。所以,普通索引樹比主鍵索引樹小很多。對於 count 這樣的操作,遍歷哪個索引樹得到的結果邏輯上都是一樣的。因此,mysql 優化器會找到最小的那棵樹來遍歷。在保證邏輯正確的前提下,儘量減少...

我該怎麼辦!

今天是我比較難受的一天,發現有些事情不到最後是不知什麼結局,或許你的一萬種猜想沒有一種實現,哎,作業雖然交了,但我還是心裡難受,我懂得了很多,不應對別人抱太大希望,應該自己去努力,不論結果怎麼樣但心裡是甜的,不堅持到最後一刻,或許成功還是不屬於你,就像我們副部,何苦堅持那麼久,幹了那麼多事,挨罵也接...

我該怎麼辦

想了好久,不知道該怎麼辦,家裡情況這個樣子,如今真的不知道是去是留。父親癱瘓在床,母親有些神經不正常,我應該是去上學還是留下來照顧他們。說實話,我一點都不想留下來,我沒有這個毅力,沒有一直照顧父親的毅力,也許時間長了我會厭煩,不知道說出這種話是不是算很不孝,1月份我在醫院的時候就是一直呆在了父親身邊...