MySQL千万级数据表优化实战
MySQL千万级数据表优化实战
数据量大导致的问题
许多人提到的阿里规定500W数据就要分库分表。实际上,这个500w并不是定义死的,而是与MySQL的配置以及机器的硬件有关。MySQL为了提升性能,会将表的索引装载到内存中。但是当表的数据到达一定的量的时候,会导致内存无法存储这些索引。无法存储索引,就只能进行磁盘IO,从而导致性能下降。
实战调优
一张表,数据有1000w,目前只有一个主键索引
查询所有大概16s,如下图所示:
通常我们一个后台系统,比如这个是一个电商平台,这个是用户表。后台管理系统,一般会查询这些用户信息,做一些操作,比如后台直接新增用户,或者删除用户这些操作。
1. 两个需求的出现
所以这里就诞生了两个需求, 一个是查询count,一个是分页查询 。我们分别来测试一下count用的时间和分页查询所用的时间。
从上面查询所用时间可以看出来,如果是分页查询的话,查询的数据越往后用时是越长的,查询count也需要
1.7s。这显然是不符合我们的要求的。所以,这里我们就需要优化。
2. 尝试索引优化无效
我们这里进行索引优化试试。
首先看一下这是 只有主键索引 的执行计划。
通过图可以看见 执行计划修改 了,虽然type是从all->index,走了sindex索引,但是实际上查询速度没有发生改变。
其实, 创建联合索引 ,是为了有条件查询的时候速度更快,而不是全表查询。
所以这就是有联合索引和无索引的差距。
这里基本上可以证明, 加了索引和不加索引 ,进行 全表查询 的时候,效率就是会 很慢 。
3. 单独建表存储每张表的count值
既然索引这个结果已经不好使了,那就只能找其他方案了。我们可以单独 把count存储到一个表里面 。
这里说一下,这种表一般不会查所有,只会查询一条,所以建表的时候,可以 建成hash 。
count默认点进去了,没有选择查询条件,那就直接查询这个count。这里其实就优化了1.7s。
4. 存在条件查询时使用索引提速
count就进行优化完了。如果上面 有选择条件 的话,就可以 建立索引 ,通过走索引筛选的形式来查询,这样就可以不用读这个count了。
5. 分页查询优化
那么,count是没问题了,分页查询优化要如何优化呢?这里可以 使用子查询 来优化。
其实子查询这种写法,判断id,其实就是通过覆盖索引来查询,效率会大大增加。
6. 补充
但是如果说数据量太大了,还是 建议走es或者进行一些默认选择 ,count可以单独列出来。
总结
- 优化查询count :表数据大时,查询表count会很慢。所以另建一个表来存两个数据,即这个表的名称和所对应的count数。
- 分页查询优化 :给表数据创建索引,因为在有索引的情况下条件查询会比较快,然后进行子查询。