論証select count(*)とselect count(1)


今日、同僚が転載した「select count(*)とselect count(1)の違い」のブログを見て、興味を持って、文の中で提出した結論を検証したいと思っています.
内容から見ると、主に主キーがあるかどうかの影響があるので、
ステップ1:test 1(プライマリ・キーあり)、test 2(プライマリ・キーなし)の2つのテーブルを作成します.
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;

ステップ2:40万件のデータを挿入
DROP PROCEDURE inserttest;
CREATE PROCEDURE inserttest()
BEGIN
	DECLARE i INT DEFAULT 1;
	WHILE i < 400000 DO
-- test1  test1,test2  test2
		INSERT INTO test1 VALUES(i, i);
		SET i = i+1;
	END WHILE;
END

CALL inserttest;

ステップ3:第1の観点「テーブルにプライマリ・キーがない場合、count(1)はcount(*)より速い」を論証する
10回テストしました(test 2テーブルにはプライマリ・キーがなく、紙面に限り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.107 s
時間:0.105 s
2
時間:0.106 s
時間:0.105 s
3
時間:0.105 s
時間:0.106 s
4
時間:0.106 s
時間:0.106 s
5
時間:0.106 s
時間:0.108 s
6
時間:0.106 s
時間:0.103 s
7
時間:0.107 s
時間:0.106 s
8
時間:0.104 s
時間:0.103 s
9
時間:0.105 s
時間:0.105 s
10
時間:0.105 s
時間:0.110 s
結論:この観点は信じられないが,結果データからcount(1)はcount(*)より平均時間がやや短いかもしれないが,必ずしもそうではない.
ステップ4:第2の観点「表はプライマリ・キーがある場合、プライマリ・キーがcount条件として最も速い」を論証する
10回テストしました(test 1テーブルにはプライマリ・キーがあり、紙面に限り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.052 s
時間:0.053 s
時間:0.059 s
2
時間:0.053 s
時間:0.052 s
時間:0.060 s
3
時間:0.052 s
時間:0.052 s
時間:0.059 s
4
時間:0.052 s
時間:0.053 s
時間:0.060 s
5
時間:0.054 s
時間:0.052 s
時間:0.059 s
6
時間:0.052 s
時間:0.054 s
時間:0.059 s
7
時間:0.051 s
時間:0.053 s
時間:0.060 s
8
時間:0.052 s
時間:0.053 s
時間:0.061 s
9
時間:0.054 s
時間:0.053 s
時間:0.059 s
10
時間:0.071 s
時間:0.052 s
時間:0.062 s
11
時間:0.051 s
時間:0.052 s
時間:0.059 s
12
時間:0.051 s
時間:0.052 s
時間:0.059 s
13
時間:0.052 s
時間:0.053 s
時間:0.059 s
結論:countはテーブルにプライマリ・キーがある場合はプライマリ・キーがない場合よりも速いが,プライマリ・キーがcount条件である場合が最も遅く,count(1)は多くの場合より性能が優れている.
ステップ5:「テーブルが1つのフィールドしかないときにcount(*)が一番速い」と論証したいのですが、テーブルが1つのフィールドしかない場合は少ないので、論証しません.
ステップ6:「count(*)とcount(1)の統計にnullが含まれ、count(カラム名)にnull値が含まれていないことを論証する」
まずtest 1テーブルの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値が含まれません.
ステップ7:select sum(1)の使用について説明します.主にsumメソッドの計算結果はパラメータ値1またはその他の条件を満たす行数の積です.
もちろんsum(1)は行数を統計するためにも使用できます.次に、null値とプライマリ・キーを持つテーブルtest 1をテストしました.データは次のとおりです.
回数
count(1)
count(*)
count(id)
count(value)
SUM(1)
1
時間:0.052 s
時間:0.052 s
時間:0.060 s
時間:0.091 s
時間:0.104 s
2
時間:0.054 s
時間:0.051 s
時間:0.060 s
時間:0.090 s
時間:0.105 s
3
時間:0.053 s
時間:0.051 s
時間:0.059 s
時間:0.093 s
時間:0.100 s
4
時間:0.052 s
時間:0.053 s
時間:0.060 s
時間:0.094 s
時間:0.102 s
5
時間:0.051 s
時間:0.052 s
時間:0.059 s
時間:0.091 s
時間:0.102 s
結論:sum(1)が統計行数として最も性能が悪い.
tips:私のテスト結果が原作者と合わないところがあるかもしれませんが、理解が間違っているところがあれば指摘してください.私はmysqlを使っています.