牛骨文教育服务平台(让学习变的简单)
博文笔记

[MySQL] count(*) vs count(1) vs count(column)

创建时间:2016-10-21 投稿人: 浏览次数:2606

MySQL版本:5.7.9

数据表结构为:
category: InnoDB 引擎,无索引

CREATE TABLE `category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(220) NOT NULL,
  `created_time` datetime NOT NULL,
  `updated_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10277277 DEFAULT CHARSET=utf8

category2: InnoDB 引擎,name 字段有索引

CREATE TABLE `category2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(220) NOT NULL,
  `created_time` datetime NOT NULL,
  `updated_time` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `Index` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=10277277 DEFAULT CHARSET=utf8

category3: MyISAM 引擎,无索引

CREATE TABLE `category3` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(220) NOT NULL,
  `created_time` datetime NOT NULL,
  `updated_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=10277277 DEFAULT CHARSET=utf8

category4: MyISAM 引擎,name字段有索引

CREATE TABLE `category4` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(220) NOT NULL,
  `created_time` datetime NOT NULL,
  `updated_time` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `Index` (`name`) USING BTREE
) ENGINE=MyISAM AUTO_INCREMENT=10277277 DEFAULT CHARSET=utf8

注:表的数据完全一致,数据量:10277276 行。

一、count(*) vs count(1)

1、对以下语句进行测试(不带where条件)

select count(*) from category;
select count(1) from category;

各执行5次结果为:

执行次数 category count(*) category count(1) category2 count(*) category2 count(1) category3 count(*) category3 count(1) category4 count(*) category4 count(1)
1 1.26 s 1.22 s 1.22 s 1.23 s 0.00 s 0.00 s 0.00 s 0.00 s
2 1.24 s 1.20 s 1.24 s 1.24 s 0.00 s 0.00 s 0.00 s 0.00 s
3 1.22 s 1.22 s 1.22 s 1.23 s 0.00 s 0.00 s 0.00 s 0.00 s
4 1.22 s 1.20 s 1.23 s 1.23 s 0.00 s 0.00 s 0.00 s 0.00 s
5 1.23 s 1.24 s 1.24 s 1.22 s 0.00 s 0.00 s 0.00 s 0.00 s



从以上结果可以看出:
1、不带where条件下,count(*) 和 count(1) 查询性能大致相同;
2、 MyISAM 引擎性能最好,这是由于 MySQL 对 MyISAM 引擎的优化:该引擎存储了当前数据总行数,当执行无where条件的count查询时,直接返回该变量(可参看MySQL官方文档)。

2、对以下语句进行测试(带where条件)

select count(*) from category where name = "cate_1000";
select count(1) from category where name = "cate_1000";

各执行5次结果为:

执行次数 category count(*) category count(1) category2 count(*) category2 count(1) category3 count(*) category3 count(1) category4 count(*) category4 count(1)
1 2.27 s 2.29 s 0.00 s 0.00 s 1.72 s 1.61 s 0.00 s 0.00 s
2 2.28 s 2.30 s 0.00 s 0.00 s 1.49 s 1.67 s 0.00 s 0.00 s
3 2.34 s 2.30 s 0.00 s 0.00 s 1.48 s 1.59 s 0.00 s 0.00 s
4 2.35 s 2.25 s 0.00 s 0.00 s 1.47 s 1.66 s 0.00 s 0.00 s
5 2.33 s 2.23 s 0.00 s 0.00 s 1.52 s 1.69 s 0.00 s 0.00 s



从以上结果可以看出:
1、带where条件时,count(*) 和 count(1) 性能大致相同;
2、带索引条件下,性能远远超过不带索引情况;
3、不带索引时,MyISAM 执行 count 性能比 InnoDB 性能好;


综上:count(*) 和 count(1) 性能大致相同。

二、count(id)(主键) vs count(name)(普通列)

1、对以下语句进行测试(不带where条件)

select count(id) from category;
select count(name) from category;

各执行5次结果为:

执行次数 category count(id) category count(name) category2 count(id) category2 count(name) category3 count(id) category3 count(name) category4 count(id) category4 count(name)
1 1.41 s 1.47 s 1.41 s 1.50 s 0.00 s 0.00 s 0.00 s 0.00 s
2 1.42 s 1.48 s 1.41 s 1.47 s 0.00 s 0.00 s 0.00 s 0.00 s
3 1.41 s 1.48 s 1.40 s 1.48 s 0.00 s 0.00 s 0.00 s 0.00 s
4 1.40 s 1.48 s 1.44 s 1.48 s 0.00 s 0.00 s 0.00 s 0.00 s
5 1.40 s 1.45 s 1.42 s 1.47 s 0.00 s 0.00 s 0.00 s 0.00 s



以上结果可以看出:
1、count(id) 和 count(name) 性能大致相同;
2、不带where条件时,执行count(column)性能和有无索引无关;

2、对以下语句进行测试(带where条件)

select count(id) from category where name = "cate_1000"; 
select count(name) from category where name = "cate_1000"; 

各执行5次结果为:

执行次数 category count(id) category count(name) category2 count(id) category2 count(name) category3 count(id) category3 count(name) category4 count(id) category4 count(name)
1 2.50 s 2.29 s 0.00 s 0.00 s 1.50 s 1.47 s 0.00 s 0.00 s
2 2.66 s 2.25 s 0.00 s 0.00 s 1.48 s 1.46 s 0.00 s 0.00 s
3 2.67 s 2.28 s 0.00 s 0.00 s 1.53 s 1.46 s 0.00 s 0.00 s
4 2.50 s 2.25 s 0.00 s 0.00 s 1.49 s 1.49 s 0.00 s 0.00 s
5 2.65 s 2.28 s 0.00 s 0.00 s 1.63 s 1.48 s 0.00 s 0.00 s



以上结果可以看出:
1、InnoDB 引擎下,带where参数且无索引时,count(id) (主键)性能比 count(column)(普通列)性能差;
2、不带索引情况下,MyISAM 执行 count(column) 性能比 InnoDB性能好;


综上,
1、大多数情况下,环境相同时,count(id) 和 count(name) 性能大致相同;
2、InnoDB引擎下,带where条件且无索引时,count(id)性能比count(name)差;

三、总结

1、无where条件时:
MyISAM( count(*) = count(1) = count(id) = count(name) ) > InnoDB( count(*) = count(1) > count(id) = count(name) )

2、带where条件时:
(1)、查询字段有索引时,MyISAM、InnoDB引擎下:
count(*) = count(1) = count(id) = count(name)

(2)、查询字段无索引时:
MyISAM( count(*) = count(1) = count(id) = count(name) ) > InnoDB( count(*) = count(1) = count(name) > count(id) )
注:有索引性能 大于 无索引。

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。