在mysql中很多朋友在写统计count时每次可能都不一样如,count(id) count(1) count(*)这三个统计出来的结果是一样的,但它们之间的性能有比较过吗?下面我来给大家举例说明一下.
表结构如下,代码如下:
- mysql>showcreatetableuserG;
- ***************************1.row***************************
- Table:user
- CreateTable:CREATETABLE`user`(
- `id`int(10)unsignedNOTNULLAUTO_INCREMENT,
- `name`varchar(50)NOTNULL,
- `pwd`varchar(50)NOTNULL,
- `email`varchar(100)NOTNULL,
- `phone`varchar(30)NOTNULL,
- `sex`enum('F','M','N')NOTNULLDEFAULT'N',
- `addres`varchar(100)NOTNULL,
- `tag`varchar(100)NOTNULL,
- PRIMARYKEY(`id`),
- KEY`name`(`name`)
- )ENGINE=InnoDBAUTO_INCREMENT=5000003DEFAULTCHARSET=utf8COMMENT='用户表'
- 1rowinset(0.00sec)
下面做一下explain,1、count(id),代码如下:
- mysql>selectcount(id)fromuser;
- +-----------+
- |count(id)|
- +-----------+
- |5000002|
- +-----------+
- 1rowinset(1.93sec)mysql>explainselectcount(id)fromuser;
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|+----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- |1|SIMPLE|user|index|NULL|name|152|NULL|4998401|Usingindex|+----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+1rowinset(0.05sec)2、count(1)
- mysql>selectcount(1)fromuser;
- +----------+
- |count(1)|
- +----------+
- |5000002|
- +----------+
- 1rowinset(0.90sec)mysql>explainselectcount(1)fromuser;
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- |1|SIMPLE|user|index|NULL|name|152|NULL|4998401|Usingindex|
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- 1rowinset(0.00sec)3、count(*)
- mysql>selectcount(*)fromuser;
- +----------+
- |count(*)|
- +----------+
- |5000002|
- +----------+
- 1rowinset(0.87sec)mysql>explainselectcount(*)fromuser;
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- |1|SIMPLE|user|index|NULL|name|152|NULL|4998401|Usingindex|
- +----+-------------+-------+-------+---------------+------+---------+------+---------+-------------+
- 1rowinset(0.00sec)
比较三个查询,explain的结果一模一样,这说明这三个的效率是一样的吗?再看看下面三个操作,带上where条件 sex='F',以下三个操作中间均会重启mysql服务,代码如下:
- 1、count(id)
- mysql>selectcount(id)fromuserwheresex='F';
- +-----------+
- |count(id)|
- +-----------+
- |1681259|
- +-----------+
- 1rowinset(18.87sec)
- mysql>explainselectcount(id)fromuserwheresex='F';
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- |1|SIMPLE|user|ALL|NULL|NULL|NULL|NULL|4998401|Usingwhere|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- 1rowinset(0.00sec)2、count(1)
- mysql>selectcount(1)fromuserwheresex='F';
- +----------+
- |count(1)|
- +----------+
- |1681259|
- +----------+
- 1rowinset(4.81sec)
- mysql>explainselectcount(1)fromuserwheresex='F';
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- |1|SIMPLE|user|ALL|NULL|NULL|NULL|NULL|4998401|Usingwhere|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- 1rowinset(0.00sec)3、count(*)
- mysql>selectcount(*)fromuserwheresex='F';
- +----------+
- |count(*)|
- +----------+
- |1681259|
- +----------+
- 1rowinset(4.69sec)
- mysql>explainselectcount(*)fromuserwheresex='F';
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- |id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+//phpfensi.com
- |1|SIMPLE|user|ALL|NULL|NULL|NULL|NULL|4998401|Usingwhere|
- +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
- 1rowinset(0.00sec)
以上三种查询有一些差别,其中count(id)用时最长,count(*)比count(1)速度要稍微快一点.
两组查询,带条件的都没有使用到索引,扫描了全表,而没有条件的则使用了索引name,所以在应用中尽量不使用count(*)和count(1),杜绝使用count(primary_key).
网上有很多资料说:
没有主键,count(1)比count(*)快;
有主键的话,count(primary_key)最快,但是在上面的测试中发现,count(primary_key)是最慢的,难道是测试不准确?这个有待验证。
如果表只有一个字段,则count(*)是最快的.
说明:
count(1)中的1并不是指第一个column;
count(*)和count(1)一样,包括对值为NULL的统计;
count(column)不包括对值为NULL的统计,这里的column指的不是primary_key;