論證-select count(*)和select count(1)的區別,-selectcount
前言:今天看到同事轉載的一篇《select count(*)和select count(1)的區別》的博文,興緻所致,就像對文中提出的結論進行驗證一下:
從內容來看,主要是有主鍵和沒有主鍵的影響,那麼
第一步:建立test1(有主鍵),test2(無主鍵)兩張表
CREATE TABLE `test1` ( `id` int(12) NOT NULL AUTO_INCREMENT, `value` int(12) NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=400000 DEFAULT CHARSET=utf8;
CREATE TABLE `test2` ( `id` int(12) NOT NULL, `value` int(12) NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8;
第二步:插入4萬條資料
DROP PROCEDURE inserttest;CREATE PROCEDURE inserttest()BEGINDECLARE i INT DEFAULT 1;WHILE i < 400000 DO-- test1表為test1,test2表為test2INSERT INTO test1 VALUES(i, i);SET i = i+1;END WHILE;ENDCALL inserttest;
第三步:論證第一個觀點“表沒有主鍵的情況下,count(1)比count(*)快”我們測試10遍(test2表沒有主鍵,限於篇幅只列出10個)
SELECT SQL_NO_CACHE COUNT(1) as ooo FROM test2;SELECT SQL_NO_CACHE COUNT(*) as aaa FROM test2;
結果資料
次數 |
count(1) |
count(*) |
1 |
時間: 0.107s |
時間: 0.105s |
2 |
時間: 0.106s |
時間: 0.105s |
3 |
時間: 0.105s |
時間: 0.106s |
4 |
時間: 0.106s |
時間: 0.106s |
5 |
時間: 0.106s |
時間: 0.108s |
6 |
時間: 0.106s |
時間: 0.103s |
7 |
時間: 0.107s |
時間: 0.106s |
8 |
時間: 0.104s |
時間: 0.103s |
9 |
時間: 0.105s |
時間: 0.105s |
10 |
時間: 0.105s |
時間: 0.110s |
結論:該觀點不值得相信,從結果資料來看,count(1)比count(*)平均時間可能稍短一點,但是並不總是這樣。第四步:論證第二個觀點“表在有主鍵的情況下,主鍵作為count條件時最快”我們測試10遍(test1表有主鍵,限於篇幅只列出10個)
SELECT SQL_NO_CACHE COUNT(1) as ooo FROM test1;SELECT SQL_NO_CACHE COUNT(*) as aaa FROM test1;SELECT SQL_NO_CACHE COUNT(id) as aaa FROM test1;
結果資料(忍不住多列了3個)
次數 |
count(1) |
count(*) |
count(id) |
1 |
時間: 0.052s |
時間: 0.053s |
時間: 0.059s |
2 |
時間: 0.053s |
時間: 0.052s |
時間: 0.060s |
3 |
時間: 0.052s |
時間: 0.052s |
時間: 0.059s |
4 |
時間: 0.052s |
時間: 0.053s |
時間: 0.060s |
5 |
時間: 0.054s |
時間: 0.052s |
時間: 0.059s |
6 |
時間: 0.052s |
時間: 0.054s |
時間: 0.059s |
7 |
時間: 0.051s |
時間: 0.053s |
時間: 0.060s |
8 |
時間: 0.052s |
時間: 0.053s |
時間: 0.061s |
9 |
時間: 0.054s |
時間: 0.053s |
時間: 0.059s |
10 |
時間: 0.071s |
時間: 0.052s |
時間: 0.062s |
11 |
時間: 0.051s |
時間: 0.052s |
時間: 0.059s |
12 |
時間: 0.051s |
時間: 0.052s |
時間: 0.059s |
13 |
時間: 0.052s |
時間: 0.053s |
時間: 0.059s |
結論:count在表有主鍵的時候比沒有主鍵的時候快,但是主鍵作為count條件時最慢,count(1)在多數情況下效能更優。第五步:本來想論證“表在只有一個欄位的時候count(*)最快”,但是很少情況下表只有一個欄位,我就不論證了。第六步:論證“count(*)和count(1)時統計包括null的,而count(列名)不包含null值”我們先將test1表的value列修改為可以為空白
ALTER TABLE `test1`MODIFY COLUMN `value` int(12) NULL AFTER `id`;
再將其中13行資料修改為null
UPDATE `test1` SET `value`=NULL WHERE (`id`='13')
通過以下語句
SELECT SQL_NO_CACHE COUNT(1) as ooo FROM test1;SELECT SQL_NO_CACHE COUNT(*) as aaa FROM test1;SELECT SQL_NO_CACHE COUNT(id) as aaa FROM test1;SELECT SQL_NO_CACHE COUNT(value) as aaa FROM test1;
資料證據
count(1) |
count(*) |
count(id) |
count(value) |
399999 |
399999 |
399999 |
399998 |
結論:count(*)和count(1)時統計包括null的,而只有count(有空值的列)不包含null值。第七步:對於select sum(1)的使用介紹,主要是說sum方法的計算結果是參數值1或者其他和滿足條件行數的乘積當然也就是說sum(1)也可以用來統計行數,然後我測試了一下效能(測試有null值並且有主鍵的表test1),資料如下:
次數 |
count(1) |
count(*) |
count(id) |
count(value) |
SUM(1) |
1 |
時間: 0.052s |
時間: 0.052s |
時間: 0.060s |
時間: 0.091s |
時間: 0.104s |
2 |
時間: 0.054s |
時間: 0.051s |
時間: 0.060s |
時間: 0.090s |
時間: 0.105s |
3 |
時間: 0.053s |
時間: 0.051s |
時間: 0.059s |
時間: 0.093s |
時間: 0.100s |
4 |
時間: 0.052s |
時間: 0.053s |
時間: 0.060s |
時間: 0.094s |
時間: 0.102s |
5 |
時間: 0.051s |
時間: 0.052s |
時間: 0.059s |
時間: 0.091s |
時間: 0.102s |
結論:sum(1)作為統計行數時,效能最差。
tips:可能我的測試結果和原作者有不符的地方,如果有理解有誤的地方請指正。