myIsam引擎把一個表的總行數存在了磁盤上,因此執行count(*)會直接返回結果,效率很高 #但是myisam不支持事物
innodb引擎需要把數據一行行從引擎里讀出來,然后計數累加。
innodb由於多版本並發控制機制,同一時刻不同回話拿到的結果可能都不相同,所以不能直接將總行數存儲在磁盤上。
比如同一時刻執行了三個會話 :
A會話: select count(*) from t #比如返回值為10
B會話: begin insert into 一條數據 ; select count(*) from t #返回值為11
C回話: insert into 倆條數據 ; select count(*) from t #返回值12
show table status 返回字段 TABLE_ROW用於顯示這個表當前有多少行,但是由於索引統計的值是通過采樣來估算的,所以不准確。
小結:
myisam統計行數效率快,但是不支持事物
show tables status統計行數,結果不准確,精確度僅有百分之50左右
innodb引擎統計行數,會遍歷全表,結果精確,但是太耗費性能。
給出的解決方案:
通過在數據庫中建表保存計數,利用innodb引擎支持事物的優點,保持數據在邏輯上一直的前提下,快速獲取結果。
count():mysql聚合函數,對返回的結果集一行行判斷,不是null,累計值就+1,不是就不+。最后返回累計值。
不同count()的用法:
count(主鍵id),innodb會遍歷整張表,將主鍵id上的值都取出來,返回給server層,server層判斷不為null的前提下,按行累加
count(1),innodb遍歷整張表,不取值。返回給server層,server層對於返回的每一行,都會放一個數字1 進去,不為空的話按行累加
count(字段),看字段默認是否允許為null,分別進行判斷
count(*),不會將全部字段取出來,專門做了優化,不取值。肯定不是null,按行累加
性能:count(*)>count(1)>count(主鍵)>count(字段)