select count(*) 應該是一個比較常用的語句,用來統計記錄行數。
但是,慢慢地你會發現,這個語句越來越慢了,為什麼呢?
count(*) 的實現方式
首先,我們來看下它的實現方式。
MySQL 中,不同的存儲引擎,count(*) 的實現方式是不同的。
1、MyISAM 引擎,比較簡單粗暴,直接將表的總行數存儲在磁碟上,因此效率很高;
2、InnoDB 引擎中,執行時,需要一行行的把數據查出來,然後累加;
為啥 MyISAM 就可以這樣做呢?因為它不支持事務啊,不用擔心數據不一致的問題。
而 InnoDB 就不一樣了。
由於 MVCC 的存在,InnoDB 在當前執行環境下,對一共有多少數據行是不確定的,比如:
假設,表 t 中有 1000 條數據,有下面三個用戶並行的會話:
1、A 啟動事務,查詢表的總行數;
2、C 直接插入一條數據,然後查詢總行數;
3、B 啟動事務,插入一條數據,然後查詢總行數;
4、C 查詢總行數;
注意,上面啟動的事務都沒有提交。