對這個問題有興趣是源於一次開發中遇到要統計人數的需求。相似於「獲得」專欄的訂閱數。mysql
可是個人數據量比這個大不少,而對數據的準確性要求就不那麼高。因此首先要明確需求。其餘答案有的說了用緩存,有的答案對比了count(*)、count(1)的區別,都很好,可是我認爲仍是要看一下題主的場景。我根據我實際開發的經驗總結以下幾個方面,FYI。redis
TABLE_ROWS
The number of rows. Some storage engines, such as MyISAM, store the exact count. For other storage engines, such as InnoDB, this value is an approximation, and may vary from the actual value by as much as 40% to 50%. In such cases, use SELECT COUNT(*) to obtain an accurate count.
這種場景通常出如今帳務上,好比有多少人打款。並且估計DAU在億級別的公司可能纔會遇到。這裏最關鍵的問題仍是一致性的要求。在併發系統中,看看咱們用redis,咱們看看會出現什麼樣的一致性問題:sql
時間 A processor B processor T1 插入數據 T2 1.redis#get計數器;2. 查詢最新的N條數據 T3 redis#incr
在T2的時間點的時候會出現數據不一致,B看到的是數據已經更新,可是數據庫還沒更新。咱們就在想,若是放到一個事務裏面,就能夠完美解決這個問題了呀。因爲事務,innoDB不支持像MyISAM準確計數,解鈴還須繫鈴人,因此咱們建一個計數表(count_table)+事務,解這個問題了。數據庫
時間 會話A 會話B T1 begin; 在計數表中插入一條數據; T2 begin; 1. 讀count_table; 2. 查詢最新的N條數據 commit; T3 更新conut_table; commit;
在T1的時候,若是採用Mysql默認的事務隔離級別:讀提交。由於T1事務尚未提交,因此插入的數據,B是讀不到的,因此從邏輯上來講是一致的。緩存
抱歉,沒遇到過。若是你以爲你遇到了,你的架構須要你從新design and review,相信我。服務器
不少時候咱們的業務場景不是數據量多,而是條件複雜。這其實就是一個查詢優化的問題了,和是否是count(*)沒有關係,那麼有如下兩招經常使用,這個得具體問題具體分析了。好比時間維度能夠加一個索引來優化;架構
select * from table_name where a = x and b = x;
結合mysql的一些索引查詢知識,咱們能夠大體得出以下結論。併發
建議直接使用count(*)。app