1. 程式人生 > >MySQL的統計總數count(*)與count(id)或count(欄位)的之間的各自效率效能對比

MySQL的統計總數count(*)與count(id)或count(欄位)的之間的各自效率效能對比

執行效果:


1.  count(1) and count(*)

當表的資料量大些時,對錶作分析之後,使用count(1)還要比使用count(*)用時多了! 
從執行計劃來看,count(1)和count(*)的效果是一樣的。 但是在表做過分析之後,count(1)會比count(*)的用時少些(1w以內資料量),不過差不了多少。 
 
如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。 
因為count(*),自動會優化指定到那一個欄位。所以沒必要去count(1),用count(*),sql會幫你完成優化的 因此:count(1)和count(*)基本沒有差別! 
 
2. count(1) and count(欄位)
兩者的主要區別是
(1) count(1) 會統計表中的所有的記錄數,包含欄位為null 的記錄。
(2) count(欄位) 會統計該欄位在表中出現的次數,忽略欄位為null 的情況。即不統計欄位為null 的記錄。 


count(*) 和 count(1)和count(列名)區別  

執行效果上:  
count(*)包括了所有的列,相當於行數,在統計結果的時候,不會忽略列值為NULL  
count(1)包括了忽略所有列,用1代表程式碼行,在統計結果的時候,不會忽略列值為NULL  
count(列名)只包括列名那一列,在統計結果的時候,會忽略列值為空(這裡的空不是隻空字串或者0,而是表示null)的計數,即某個欄位值為NULL時,不統計。

執行效率上:  
列名為主鍵,count(列名)會比count(1)快  
列名不為主鍵,count(1)會比count(列名)快  
如果表多個列並且沒有主鍵,則 count(1) 的執行效率優於 count(*)  
如果有主鍵,則 select count(主鍵)的執行效率是最優的  
如果表只有一個欄位,則 select count(*)最優。


例項分析

mysql> create table counttest(name char(1), age char(2));
Query OK, 0 rows affected (0.03 sec)
 
mysql> insert into counttest values
    -> ('a', '14'),('a', '15'), ('a', '15'), 
    -> ('b', NULL), ('b', '16'), 
    -> ('c', '17'),
    -> ('d', null), 
    ->('e', '');
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0
 
mysql> select * from counttest;
+------+------+
| name | age  |
+------+------+
| a    | 14   |
| a    | 15   |
| a    | 15   |
| b    | NULL |
| b    | 16   |
| c    | 17   |
| d    | NULL |
| e    |      |
+------+------+
8 rows in set (0.00 sec)
 
mysql> select name, count(name), count(1), count(*), count(age), count(distinct(age))
    -> from counttest
    -> group by name;
+------+-------------+----------+----------+------------+----------------------+
| name | count(name) | count(1) | count(*) | count(age) | count(distinct(age)) |
+------+-------------+----------+----------+------------+----------------------+
| a    |           3 |        3 |        3 |          3 |                    2 |
| b    |           2 |        2 |        2 |          1 |                    1 |
| c    |           1 |        1 |        1 |          1 |                    1 |
| d    |           1 |        1 |        1 |          0 |                    0 |
| e    |           1 |        1 |        1 |          1 |                    1 |
+------+-------------+----------+----------+------------+----------------------+
5 rows in set (0.00 sec)


額外參考資料:http://blog.csdn.net/lihuarongaini/article/details/68485838
--------------------- 
作者:BigoSprite 
來源:CSDN 
原文:https://blog.csdn.net/iFuMI/article/details/77920767 

 

 

 

 

 

另外參考:https://blog.csdn.net/blueinsect314/article/details/17327253

mysql的count優化總體上有以下注意事項:
1.任何情況下SELECT COUNT(*) FROM tablename是最優選擇;

2.儘量減少SELECT COUNT(*) FROM tablename WHERE COL = 'value’ 這種查詢;

3.杜絕SELECT COUNT(COL) FROM tablename的出現。 


COUNT(*)和COUNT(欄位名)他們的效能參考對比:
 

COUNT(*)與COUNT(COL)

網上搜索了下,發現各種說法都有:

比如認為COUNT(COL)比COUNT(*)快的;

認為COUNT(*)比COUNT(COL)快的;

還有朋友很搞笑的說到這個其實是看人品的。

在不加WHERE限制條件的情況下,COUNT(*)與COUNT(COL)基本可以認為是等價的;

但是在有WHERE限制條件的情況下,COUNT(*)會比COUNT(COL)快非常多;

具體的資料參考如下:

mysql> SELECT COUNT(*) FROM cdb_posts where fid = 604;

+————+

| COUNT(fid) |

+————+

| 79000 |

+————+

1 row in set (0.03 sec)

mysql> SELECT COUNT(tid) FROM cdb_posts where fid = 604;

+————+

| COUNT(tid) |

+————+

| 79000 |

+————+

1 row in set (0.33 sec)

mysql> SELECT COUNT(pid) FROM cdb_posts where fid = 604;

+————+

| COUNT(pid) |

+————+

| 79000 |

+————+

1 row in set (0.33 sec)

  

COUNT(*)通常是對主鍵進行索引掃描,而COUNT(COL)就不一定了,另外前者是統計表中的所有符合的紀錄總數,而後者是計算表中所有符合的COL的紀錄數。還有有區別的。

COUNT時的WHERE

這點以前就寫過,詳細請看《Mysql中count(*),DISTINCT的使用方法和效率研究》

簡單說下,就是COUNT的時候,如果沒有WHERE限制的話,MySQL直接返回儲存有總的行數

而在有WHERE限制的情況下,總是需要對MySQL進行全表遍歷。

 

在MySQL5下,select count(*) 和select count(id)是完全一樣的。

表裡有300萬+條記錄。

花了0.8秒,但是我用explain檢視查詢計劃時,卻發現它沒有用primiary的index,於是強制它使用主鍵索引,結果花費了7秒!

我仔細研究了一下預設時使用的索引,居然是用的一個bit(1)上的索引,這個欄位就是一個標誌位。

 

想了一下,估計因為這個索引最小,基於bit(1),而主鍵是基於int(4)的,並且所有索引都能用於計算count(*),因為總是一條記錄對應一個索引元素。

 

因此有一個小技巧提供給樓主:如果你的表中有類似標誌位(比如是否邏輯刪除)的欄位,那麼在其上建立一個索引,會把count(*)的速度提高數倍。當然最好用bit(1)型別,而不是int或char(1)儲存標誌位,那樣會更慢。
 

mysql的count優化總結:

1.任何情況下SELECT COUNT(*) FROM tablename是最優選擇;

2.儘量減少SELECT COUNT(*) FROM tablename WHERE COL = 'value’ 這種查詢;

3.杜絕SELECT COUNT(COL) FROM tablename的出現。