MySQL数据库优化————COUNT优化

直接进入主题

索引对count语句的影响

在我们对departments表进行count查询时,使用了以下语句

select count(*) from employees;

当前employees表索引情况如图
在这里插入图片描述

只有一个主键索引
执行

explain
select count(*) from employees;

![在这里插入图片描述](https://img-blog.csdnimg.cn/c5b3b99115234070b959a0c4bed05682.png
从结果中可以看到,这时候用的是主键索引。
让我们修改一下employees表的索引
在这里插入图片描述
在last_name上创建了索引,我们再次执行explain得到结果
在这里插入图片描述
我们再一次修改employees表的索引
在这里插入图片描述
我们又在first_name上创建了索引,再一次执行explain语句
在这里插入图片描述
这一次我们用到了first_name上的索引,并且索引长度first_name上的要小于last_name上的。

得到结论:

  • 当没有非主键索引时,count查询会使用主键索引
  • 如果存在非主键索引时,count查询会使用非主键索引
  • 如果存在多个非主键索引时,count查询会使用索引长度最小的非主键索引

原因分析
我们的表使用的InnoDB引擎,那么主键索引存储的是主键+表数据,而非主键索引存储的是索引+主键。InnoDB是以页为单位的,那么存储的一行数据越小,则存储的数据越多。主键的大小是固定的,而表数据的大小肯定比一个非主键索引大,所以非主键索引存储的数据要比主键索引存储的数据量大;同理,长度小的非主键索引存储的数据也比长度大的非主键索引存储的数据量大。

count(字段)和count(*)

当我们在执行count(字段)时

select count(last_name) from employees;

执行explain语句

explain
select count(last_name) from employees;

在这里插入图片描述
得到结论,count(字段)时,只会针对该字段统计,使用这个字段上面的索引(如果有的话)。
在这里插入图片描述
如果我们将last_name上的索引删除,再次执行explain语句
在这里插入图片描述
得到结论,count(字段)时,如果该字段上没有索引,则进行的时全表扫描。
我们分别执行以下语句

select count(*) from employees;

select count(last_name) from employees;

分别得到结果
在这里插入图片描述
在这里插入图片描述
为什么会不一样呢,因为我将其中的四条数据的last_name置为了null;
结论,count(字段)会排除掉该字段值为null的数据,而count(*)不会排除,所以要根据业务需求的需要进行选择,不能无脑的任意选择一种。

count(*)和count(1)

我们来执行一下count(1)的explai语句,得到结果
在这里插入图片描述
发现该语句同样使用的是表的最小长度的非主键索引。同时查阅官方文档,有这样一段话
在这里插入图片描述
所以,count(*)和count(1)是一样的,没有性能差异。

基于存储引擎

在官方文档中还提到了
在这里插入图片描述
如果是用的MyISAM引擎,并且使用的是示例中的语句,查询速度会非常的快,因为该引擎将行数存储到了引擎。该功能是有限制的,必须是没有where条件语句的。
同时,还有这样一段话
在这里插入图片描述
从MySQL8.0.13,InnoDB引擎如果没有where条件,查询也会被优化,性能有所提升。该功能有条件的朋友可以在低版本的MySQL和8.0.13版本上的进行一下验证,这里不做演示。

汇总表

当count查询耗时过长,我们可以创建一张汇总表,统计各个表的行数。当数据发生变化时去修改对应表的行数,可以通过使用触发器自动维护实现。
这种方法的好处就是结果准确,但是需要额外的维护成本。

sql_calc_found_rows

cpunt查询往往伴随着分页查询,在进行分页查询时我们可以使用以下语句

select sql_calc_found_rows * from table limit offset,size;

然后紧接着执行

select found_rows() as 别名;

这样就能很快的返回我们想要的数据了,因为第一条语句在执行完分页查询后,会自动执行count查询。在项目中我们可以这样运用
在这里插入图片描述
这种方式,从8.0.17已经被废弃了,在以后的版本会被删除。
在这里插入图片描述

使用额外的中间件解决

将count的结果定时存入缓存中,这种方式性能比较高,结果比较准确,有误差,但是可以接受,除非在缓存更新阶段有大量的新增和删除。但是缺点就是要引入额外的组件,增加了架构的复杂度及维护成本。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL入门学习(1)。   MySQL入门学习(1) · 安装篇 PHP+MySQL+Linux目前已逐渐成为小型web服务器的一种经典组合。在indows环境下构筑和调试MySQL数据库是许多网站开发者的一种首选。本人在Windows98环境下初学MySQL,现将学习过程与经验总结出来供大家参考。 1、下载mysql-3.23.35-win.zip并解压; 2、运行setup.exe;选择d:\mysql,"tyical install" 3、启动mysql,有如下方法: · 方法一:使用winmysqladmin 1)、进入d::\mysql\bin目录,运行winmysqladmin.exe,在屏幕右下角的任务栏内会有一个带红色的图符 2)、鼠标左键点击该图符,选择“show me”,出现“WinMySQLAdmin”操作界面;首次运行时会中间会出现一个对话框要求输入并设置你的用户名和口令 3)、选择“My.INI setup” 4)、在“mysqld file”中选择“mysqld-opt”(win9x)或“mysqld-nt”(winNT) 5)、选择“Pick-up or Edit my.ini values”可以在右边窗口内对你的my.ini文件进行编辑 6)、选择“Save Modification”保存你的my.ini文件 7)、如果你想快速使用winmysqladmin(开机时自动运行),选择“Create ShortCut on Start Menu” 8)、测试: 进入DOS界面; 在d:\mysql\bin目录下运行mysql,进入mysql交互操作界面 输入show databases并回车,屏幕显示出当前已有的两个数据库mysql和test · 方法二:不使用winmysqladmin 1)、在DOS窗口下,进入d:/mysql/bin目录 2)、win9X下)运行: mysqld 在NT下运行: mysqld-nt --standalone 3)、此后,mysql在后台运行 4)、测试mysql:(在d:/mysql/bin目录下) a)、mysqlshow 正常时显示已有的两个数据库mysql和test b)、mysqlshow -u root mysql 正常时显示数据库mysql里的五个表: columns_priv db host tables_priv user c)、mysqladmin version status proc 显示版本号、状态、进程信息等 d)、mysql test 进入mysql操作界面,当前数据库为test 5)、mysql关闭方法: mysqladmin -u root shutdown 4、至此,MySQL已成功安装,接着可以熟悉MySQL的常用命令并创建自己的数据库了。 上篇讲了如何安装并测试MySQL,环境建好后就可以继续我们的学习了。本篇主要熟悉一写常用命令。 · 1、启动MySQL服务器 实际上上篇已讲到如何启动MySQL。两种方法: 一是用winmysqladmin,如果机器启动时已自动运行,则可直接进入下一步操作。 二是在DOS方式下运行 d:mysqlbinmysqld · 2、进入mysql交互操作界面 在DOS方式下,运行: d:mysqlbinmysql 出现: mysql 的提示符,此时已进入mysql的交互操作方式。 如果出现 "ERROR 2003: Can´t connect to MySQL server on ´localhost´ (10061)“, 说明你的MySQL还没有启动。 · 3、退出MySQL操作界面 在mysql>提示符下输入quit可以随时退出交互操作界面: mysql> quit Bye 你也可以用control-D退出。 · 4、第一条命令 mysql> select version(),current_date(); +----------------+-----------------+ | version() | current_date() | +----------------+-----------------+ | 3.23.25a-debug | 2001-05-17 | +----------------+-----------------+ 1 row in set (0.01 sec) mysql> 此命令要求mysql服务器告诉你它的版本号和当前日期。尝试用不同大小写操作上述命令,看结果如何。 结果说明mysql命令的大

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值