MySQL中COUNT查询函数如何使用
MySQL中COUNT查询函数如何使用,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
创新互联公司专注于企业网络营销推广、网站重做改版、安多网站定制设计、自适应品牌网站建设、H5页面制作、商城网站建设、集团公司官网建设、外贸网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为安多等各大城市提供网站开发制作服务。
首先创建一个表,只有id,name,sex三个字段,使用存储过程随机插入100万条数据:
select count(expr) from table;
可以看到count函数实际上需要传入expr,这个expr一般取值有以下三个:
列名:会检索对应列值不为NULL的条数。
*:查询符合条件的行数,和列值是否为NULL无关,返回结果都会返回。
常量:查询符合条件的行数,和列值是否为NULL无关,返回结果都会返回。
可以发现执行速度两条SQL语句是相差无几的,count(1)和count(*)都是查询全表数据行数,可能网上很多言论会说count(*)其实走的就是count(1)查询,所以使用count(1)查询可以节省转换时间,实际上无论count(*)还是count(1)完全一致,都是表示指定非空表达式,所以会查询所有符合条件的行数。为什么我会说这两个语句执行效果是一样的?因为Mysql官方文档写了这么一句话:
InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference.
可能有人会纳闷我们添加索引列目的不就是为了提高查询效率?平时我们检索数据属于范围查询,查询指定的数据,所以走索引可以提高查询效率,但是count(id)选择索引基数大的主键索引肯定效率更低。因为主键索引和数据文件存放在一起,所以通过主键id取条数会检索数据文件,count(id)会检索整张表,然后遍历取到每一行数据的id,然后返回server层对每一行的id,不为空count就 + 1,而count(*)一样全表检索,但是不会取id值,因为在索引树就可以得到结果,所以count(id)需要取到数据再过滤id为null的数据效率方面肯定是慢上不少的。
count(*)优化
count(*)和count(1)没什么差别,但是执行时间都得1S多,而且数据量只是100万条,所以我们肯定需要进行适当的优化。因为count(*)实际上查询会使用最小字段的索引进行优化查询,但是因为目前我们表中只有一个主键索引,刚才也说过count(id)效率比count(*)低,所以默认不使用索引查询,我们可以使用explain测试下:
可以看到查询没有走任何索引,所以效率很低是必然的。而count(*)刚才说过会默认寻找最小字段的索引优化查询,所以我们给表增加一个status字段,弄成tinyint类型,并且添加二级索引,然后测试count(*)执行时间:
count(col)
说完了count(*),我们知道了如果在需要返回全部行数时可以使用count(*),那接下来我们如果需要查询姓名不为空的总行数怎么做呢?我们可以加个where很快实现:
很显然,本次查询走索引了,加速查询的原因是什么呢?因为我们在name字段创建了一个二级索引,在无二级索引时,count操作只能全表检索数据。当我们通过二级索引统计总条数,无需扫描数据文件,因为二级索引存储的数据就是name字段的值与主键id值。所以在count(col)时就可以在字段上添加一个二级索引加快检索速率。
count函数指定where条件
这里一样得分两种情况:count(*)和count(col)。
count(*):where条件添加索引,就可以使用索引优化查询。例如我们刚才添加的type列表示用户账号是否可用,我们现在需要查询可用账户的总数量就可以这样写:
select count(*) from order_info where type = 0;
count(col): 查询列不为空的总条数并且添加where条件,就需要col添加索引并且where使用col进行条件限制,我们可以先来看下name添加索引但是where使用sex限制条件的情况:
看完上述内容,你们掌握MySQL中COUNT查询函数如何使用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
当前标题:MySQL中COUNT查询函数如何使用
文章URL:http://myzitong.com/article/gssppe.html