bash mysql count()_【MySQL】性能优化之 count(*) VS count(col)

优化mysql数据库时,经常有开发询问 count(1)和count(primary_key) VS count(*)的性能有何差异?看似简单的问题,估计会有很多人对此存在认知误区:

1. 认为count(1) 和 count(primary_key) 比 count(*) 的性能好。

2. count(column) 和 count(*) 效果是一样的。

本文对上述两点做如下测试,

测试环境:

root@yang 07:17:04>CREATE TABLE `mytab` (

->   `id` int(10) unsigned NOT NULL,

->   `v1` int(11) default NULL,

->   `v2` int(10) unsigned NOT NULL,

->   KEY `idx_id` (`id`)

-> ) ENGINE=MyISAM DEFAULT CHARSET=latin1;

Query OK, 0 rows affected (0.00 sec)

1 select语句 不含有where 条件

root@yang 07:41:11>select count(*) from mytab;

+----------+

| count(*) |

+----------+

|  2000000 |

+----------+

1 row in set (0.00 sec)

root@yang 07:41:22>select count(id) from mytab;

+-----------+

| count(id) |

+-----------+

|   2000000 |

+-----------+

1 row in set (0.00 sec)

root@yang 07:41:37>select count(v1) from mytab;

+-----------+

| count(v1) |

+-----------+

|   2000000 |

+-----------+

1 row in set (0.12 sec)

root@yang 07:41:41>select count(v2) from mytab;

+-----------+

| count(v2) |

+-----------+

|   2000000 |

+-----------+

1 row in set (0.00 sec)

以上使用了myisam表做了测试,四种查询方式的结果有所不同,注意到count(V1) 的时间是0.12s 因为myisam 表的特性其已经保存了表的总行数, count(*)相对非常快。

coun(v2) 比count(v1) 快是因为v1 字段可以为空,mysql 在执行count(col) 是表示结果集中有多少个col字段不为空的记录,mysql 存储引擎会去检查表中说有行记录中col字段是否为空,并计算出非空的个数。

2 使用带有where 条件的查询:

root@yang 01:13:13>select count(*) from t1 where id < 200000;

+----------+

| count(*) |

+----------+

|   200000 |

+----------+

1 row in set (0.06 sec)

root@yang 01:15:22>explain select count(*) from t1 where id < 200000;

+----+-------------+-------+-------+---------------+--------+---------+------+--------+--------------------------+

| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows   | Extra                    |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+--------------------------+

|  1 | SIMPLE      | t1    | range | idx_id        | idx_id | 4       | NULL | 205923 | Using where; Using index |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+--------------------------+

1 row in set (0.00 sec)

root@yang 01:15:30> select count(v1) from t1 where id < 200000;

+-----------+

| count(v1) |

+-----------+

|    200000 |

+-----------+

1 row in set (0.17 sec)

root@yang 01:15:37>explain  select count(v1) from t1 where id < 200000;

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows   | Extra       |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

|  1 | SIMPLE      | t1    | range | idx_id        | idx_id | 4       | NULL | 205923 | Using where |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

1 row in set (0.00 sec)

root@yang 01:15:42> select count(v2) from t1 where id < 200000;

+-----------+

| count(v2) |

+-----------+

|    200000 |

+-----------+

1 row in set (0.16 sec)

root@yang 01:15:49>explain select count(v2) from t1 where id < 200000;

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

| id | select_type | table | type  | possible_keys | key    | key_len | ref  | rows   | Extra       |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

|  1 | SIMPLE      | t1    | range | idx_id        | idx_id | 4       | NULL | 205923 | Using where |

+----+-------------+-------+-------+---------------+--------+---------+------+--------+-------------+

1 row in set (0.00 sec)

count(*) 可以使用覆盖索引 ,而count(col)不行。v2 是非空列,处理起来应该和count(*)类似才对,这里显示却和v1 字段的处理一致。如果mysql 优化器处理的足够好,检查到字段为非空时,即可和count(*) 做同样的处理,这样速度会更快一些。下面修改索引结构使用复合索引。

root@yang 01:17:07>alter table t1 drop key idx_id,add key idx_id_v1(id,v1);

Query OK, 2000000 rows affected (1.49 sec)

Records: 2000000  Duplicates: 0  Warnings: 0

root@yang 01:17:36> select count(v1) from t1 where id < 200000;

+-----------+

| count(v1) |

+-----------+

|    200000 |

+-----------+

1 row in set (0.07 sec)

root@yang 01:17:49>explain  select count(v1) from t1 where id < 200000;

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+--------------------------+

| id | select_type | table | type  | possible_keys | key       | key_len | ref  | rows   | Extra                    |

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+--------------------------+

|  1 | SIMPLE      | t1    | range | idx_id_v1     | idx_id_v1 | 4       | NULL | 196079 | Using where; Using index |

+----+-------------+-------+-------+---------------+-----------+---------+------+--------+--------------------------+

1 row in set (0.00 sec)

对于字段v1 的查询性能相对上例中提升两倍多,当然如果是生产环境可能提升更高。最终面向开发是,最好先有开发修改应用程序中的sql 避免使其选择count(col)。

对于第二个误区:认为 count(column) 和 count(*) 是一样的,其实是有差别的。请看下面的例子:

root@yang 10:01:38>create table t3 (id int ,v1 int ) engine =innodb;

Query OK, 0 rows affected (0.01 sec)

root@yang 10:03:54>insert t3 values (null,null),(1,null),(null,1),(1,null),(null,1),(1,null),(null,null);

Query OK, 7 rows affected (0.00 sec)

Records: 7  Duplicates: 0  Warnings: 0

root@yang 10:03:57>select count(id),count(id),count(v1) from t3;

+-----------+-----------+-----------+

| count(id) | count(id) | count(v1) |

+-----------+-----------+-----------+

|         3 |         3 |         2 |

+-----------+-----------+-----------+

1 row in set (0.00 sec)

count(col) 是表示结果集中有多少个column字段不为空的记录。

count(*) 是表示整个结果集有多少条记录。

3 增加对innodb 存储引擎的测试

root@yang 01:29:53>alter table t1 engine=innodb;

Query OK, 2000000 rows affected (11.25 sec)

Records: 2000000  Duplicates: 0  Warnings: 0

root@yang 01:30:26>select count(*) from t1;

+----------+

| count(*) |

+----------+

|  2000000 |

+----------+

1 row in set (0.69 sec)

对于 innodb表比myisam 表查询总行数 性能慢是因为innodb 存储引擎并没有保存行的总数,innodb 表支持mvcc ,不同的事务可能看到不同的行记录数。因此每次count(*) 和count(col)(没有使用索引的情况下) 都要对表进行索引扫描,可能大家对最终获取结果的时间有疑问,为什么myisam 表是0.17s 左右,而innodb 是0.77s ,因为innodb 表在磁盘存储的大小比myisam大,扫描的物理page更多。

root@yang 01:30:32>select count(v1) from t1;

+-----------+

| count(v1) |

+-----------+

|   2000000 |

+-----------+

1 row in set (0.77 sec)

root@yang 01:30:40>select count(v2) from t1;

+-----------+

| count(v2) |

+-----------+

|   2000000 |

+-----------+

1 row in set (0.73 sec)

在使用where条件的情况下:等值查询和使用到索引情况下 ,myisam 表和innodb的速度是几乎无差别的,具体的性能表现和where 条件有关。

root@yang 10:14:03>select count(v2) from t1 where id =20000;

+-----------+

| count(v2) |

+-----------+

|         1 |

+-----------+

1 row in set (0.00 sec)

推荐阅读:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/441156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【HihoCoder - 1851】D级上司 (树形图,dfs)

题干&#xff1a; H公司一共有N名员工&#xff0c;编号为1~N&#xff0c;其中CEO的编号是1。除了CEO之外&#xff0c;每名员工都恰好有唯一的直接上司&#xff1b;N名员工形成了一个树形结构。 我们定义X的1级上司是他的直接上司&#xff0c;2级上司是他上司的上司&#xf…

mysql录数据总是错误_MySQL数据库出错

在主库上备份表 t (假设备份快照 GTID 为 aaaa:1-10000)&#xff1b;恢复到从库&#xff1b;启动复制。这里的问题是复制起始位点是 aaaa:101&#xff0c;从库上表 t 的数据状态是领先其他表的。aaaa:101-10000 这些事务中只要有修改表 t 数据的事务&#xff0c;就会导致复制报…

linux安装mysql后怎么进去_linux安装mysql详细步骤

最近买了个腾讯云服务器&#xff0c;搭建环境。该笔记用于系统上未装过mysql的干净系统第一次安装mysql。自己指定安装目录&#xff0c;指定数据文件目录。linux系统版本&#xff1a; CentOS 7.3 64位安装源文件版本&#xff1a;mysql-5.7.21-linux-glibc2.12-x86_64.tar.gzmys…

给各位ACMer,OIer详细介绍一下Codeforces比赛

Codeforces 简称: cf(所以谈论cf的时候经常被误会成TX的那款游戏). 网址: codeforces.com   这是一个俄国的算法竞赛网站,由来自萨拉托夫州立大学、由Mike Mirzayanov领导的一个团队创立和维护,是一个举办比赛、做题和交流的平台.举办比赛和做题就不说了,“交流”指的是自带b…

【CodeForces - 278C 】Learning Languages(并查集,思维)

题干&#xff1a; The "BerCorp" company has got n employees. These employees can use m approved official languages for the formal correspondence. The languages are numbered with integers from 1 to m. For each employee we have the list of language…

java短除法获取二进制_Java十四天零基础入门-Java的数据类型介绍

不闲聊&#xff01;&#xff01;&#xff01;不扯淡&#xff01;&#xff01;&#xff01;小UP只分享Java相关的资源干货本章节目标&#xff1a;理解数据类型的作用。Java中包括哪些数据类型&#xff1f;常见的八种基本数据类型都有哪些&#xff1f;会用八种基本数据类型声明变…

【CodeForces - 151C】Win or Freeze (博弈,数学,唯一素数分解)

题干&#xff1a; You cant possibly imagine how cold our friends are this winter in Nvodsk! Two of them play the following game to warm up: initially a piece of paper has an integer q. During a move a player should write any integer number that is a non-tr…

vs怎么把textbox输入的实数放置变量里_方程的计算机处理96(3)_C++vs

计算机语言运用--数值计算9-方程的计算机处理96(3)_Cvs计算机&#xff1a;电子线路组成的计算机器。人与计算机则是通过计算机语言-符号系统说给计算机听而交流。计算机语言有低级语言-机器语言、汇编、高级语言-C/C/C#/VB/PASCAL/LISP/JAVA/PYTHON/……成百上千种之多。作为一…

【CodeForces - 151D】Quantity of Strings (字符串问题,思维推导,有坑)

题干&#xff1a; Just in case somebody missed it: this winter is totally cold in Nvodsk! It is so cold that one gets funny thoughts. For example, lets say there are strings with the length exactly n, based on the alphabet of size m. Any its substring with…

2008r装mysql_mysql5.7.17在win2008R2的64位系统安装与配置实例

安装MySql操作系统&#xff1a;Windows Server 2008 R2 StandardMySql版本&#xff1a;mysql-5.7.17-winx64第一步&#xff1a;解压mysql-5.7.17-winx64.zip到指定位置第二步&#xff1a;安装文件根目录下添加data文件夹&#xff0c;将my-default.ini重命名为my.ini第三步&…

【POJ - 2377】Bad Cowtractors (最大生成树,并查集)

题干&#xff1a; Bessie has been hired to build a cheap internet network among Farmer Johns N (2 < N < 1,000) barns that are conveniently numbered 1..N. FJ has already done some surveying, and found M (1 < M < 20,000) possible connection route…

csv转为utf8编码_读取UTF8编码的CSV并转换为UTF-16

我正在读取具有UTF8编码的CSV文件&#xff1a;ifile open(fname, "r")for row in csv.reader(ifile):name row[0]print repr(row[0])这很好用&#xff0c;并打印出我希望它打印出来的东西; UTF8编码 str &#xff1a;> \xc3\x81lvaro Salazar> \xc3\x89lodie…

【 CodeForces - 799A 】Carrot Cakes(模拟,细节,有坑)

题干&#xff1a; In some game by Playrix it takes t minutes for an oven to bake k carrot cakes, all cakes are ready at the same moment t minutes after they started baking. Arkady needs at least n cakes to complete a task, but he currently dont have any. H…

mysql 递归实现树形_Mysql实现树形递归查询

最近在做项目迁移&#xff0c;Oracle版本的迁到Mysql版本&#xff0c;遇到有些oracle的函数&#xff0c;mysql并没有&#xff0c;所以就只好想自定义函数或者找到替换函数的方法进行改造。Oracle递归查询oracle实现递归查询的话&#xff0c;就可以使用start with ... connect b…

【CH - 1401】 兔子与兔子(字符串哈希)

题干&#xff1a; 描述 很久很久以前&#xff0c;森林里住着一群兔子。有一天&#xff0c;兔子们想要研究自己的 DNA 序列。我们首先选取一个好长好长的 DNA 序列&#xff08;小兔子是外星生物&#xff0c;DNA 序列可能包含 26 个小写英文字母&#xff09;&#xff0c;然后我…

postmain请求中午乱码_完美解决Get和Post请求中文乱码的问题

对于Post请求&#xff0c;只需在Servlet或者jsp中写入如下代码就可以把解决从表单中传入的中文乱码问题request.setCharacterEncoding("utf-8");而对于Get请求&#xff0c;因为请求参数会被附加到地址栏的URL之后&#xff0c;所以不能用上面的处理方法。应该这样&…

【HDU - 5187】zhx's contest (快速幂+ 快速乘,模板)

题干&#xff1a; 2018百度之星复赛晋级名单出炉&#xff08;增加20%晋级名额&#xff09;~ zhxs contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3779 Accepted Submission(s): 1226 Problem Desc…

python批量打印word_Python使用扩展库pywin32实现批量文档打印实例

本文代码需要正确安装Python扩展库pywin32&#xff0c;建议下载whl文件进行离线安装。然后调用win32api的ShellExecute()函数来实现文档打印&#xff0c;系统会根据文档类型自动选择不同的软件进行打开并自动打印&#xff0c;如果要打印的是图片的话&#xff0c;需要手工确认一…

【牛客 - 283E】贪心只能过样例(模拟)

题干&#xff1a; 小西是单身狗&#xff0c;所以她不喜欢看到有CP在秀恩爱&#xff01; 有一天&#xff0c;小西出来闲逛&#xff0c;发现街上的行人都排成了一排&#xff0c;并且可以用这种形式表示&#xff1a; MMFMMFFFMMM 其中M表示男孩子&#xff0c;F表示女装的男孩…

apmserver导入MySQL_mysql数据库导入导出

window下1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名mysqldump -u dbuser -p dbname > dbname.sql2.导出一个表mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名mysqldump -u dbuser -p dbname users> dbname_users.sql3.导出一个数据库结…