重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
count(*)是如何实现的?
创新互联网站建设公司提供网站设计和自适应建站服务。团队由有经验的网页设计师、程序员和市场专家组成,能够提供从H5网站设计,网站制作,一元广告,模板建站到小程序开发等全方位服务。 以客户为中心,致力于为客户提供创新、高效的解决方案,帮助您打造成功的企业网站。
上述的count(*)指的是在查询的时候不加where条件,不加where条件的count(*)在不同的数据库引擎下有不同的实现:
InnoDB为什么不把总行数存起来?
由于InnoDB的事务支持,同一时刻的多个事务的查询,由于多版本并发控制的(MVCC)的原因,InnoDB表返回的行数是不确定。
InnoDB对COUNT(*)做的优化?
InnoDB是索引组织表,所有的数据都是通过B+数的方式组织起来的,主键索引的叶子节点是整行数据,普通索引的叶子节点是主键值,因此 普通索引树的大小要比主键索引树小的多 。对于count(*),MySQL优化器会找到最小的那棵索引树然后进行遍历。
如果某张大表需要经常性的进行count(*)操作,可以考虑单独建立一张表进行保存大表的记录行数。
COUNT的具体含义?
COUNT()是一个聚合函数,对于返回的结果集需要一行一行的进行判断,如果COUNT函数中的参数不为NULL,累计值就加,否则不加。
COUNT的几种用法?
COUNT(*)除了在选择索引树遍历上有优化,而且在执行的过程中不会取值,Server层按照行累加。
COUNT(主键ID),InnoDB会遍历整张表,把每一行的ID值都取出来,返回给Server层。Server层拿到ID以后,判断不可能为空,按行累加。
COUNT(1),InnoDB引擎遍历整张表,但不取值。Server层对于返回的每一行放一个数字"1"进去,判断不可能为空,按行累加。
COUNT(字段),如果字段定义为NOT NULL的话,Server层从记录中取到字段以后判断不可能为NULL,按行累加;但是如果字段允许为NULL,Server层就有可能取到为NULL的记录,此时需要把记录中的值进行判断一下,不是NULL才可以累加。
COUNT效率
COUNT(字段) COUNT(主键ID) COUNT(1) COUNT(*)
?Show
status
?一些值得监控的变量值:
?Bytes_received和Bytes_sent
?和服务器之间来往的流量。
?Com_*服务器正在执行的命令。
?Created_*在查询执行期限间创建的临时表和文件。
?Handler_*存储引擎操作。
?Select_*不同类型的联接执行计划。
?Sort_*几种排序信息。
?Show
session status like ‘Select’;
?Show profiles
?SET profiling=1;
?Show
profiles\G
?Show profile;
Show Profile 是mysql提供可以用来分析 当前会话 中语句执行的资源消耗情况,可以用于Sql调优的测量。
请读者继续看前面的图 SQL执行具体细节 ,左边 Status 列展示了一条SQL执行的从开始到清理的整个生命周期中执行的操作。如果在其生命周期阶段出现如下的情况的就要重视了:
开启 Profiling 后,mysql会留下15条最近执行的sql的 现场 , 便于我们发现问题。
Show profiles 用来查最近的15条。
Show profile 用来展示每一个SQL执行阶段的耗时清单,便于我们发现耗时最多的地方,然后以此为依据查找问题所在,最后优化SQL或者优化mysql参数。比如耗时清单创建了临时表,就要考虑表是否创建索引,如果创建了那么是否没有用到或者失效了。
总的来说 Profiling 是一个很不错的mysql性能分析工具。
第一优化你的sql和索引;
第二加缓存,memcached,redis;
第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护;
第四如果以上都做了还是慢,不要想着去做切分,mysql自带分区表,先试试这个,对你的应用是透明的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了;
第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小的系统,也就是分布式系统;
第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;
mysql数据库一般都是按照这个步骤去演化的,成本也是由低到高;