mysql存量表数据碎片与索引碎片优化

打工人

背景

最近领导分配了个任务,测试sit环境一些功能相比之前慢了许多,需要优化一下。

问题排查过程

浏览器F12查看相关接口的响应,看到底是哪个接口反应慢,根据互联网的要求,页面3秒还没有显示出来,用户体验会非常差。

查看相关代码的提交时间,这些代码一上线就没有改动过,由此以我三年职业生涯的经验推断,可能是接口相关数据库表设计不合理或者需要优化导致的问题,因而该篇文章由此诞生!

数据库单表优化步骤

设计表时:1.选择合适的字段类型

                   2.创建高性能索引

运维期间: 1.慢sql优化

                   2.mysql参数调优

                   3.数据碎片与索引碎片优化

之前我已做过数据库部分优化,今天我们所采用的的优化方案是:数据碎片与索引碎片优化

Q:为什么会产生数据碎片与索引碎片呢?

A:由于表记录delete后,只是在相应记录上表示该记录被删除出,表空间没有释放从而导致数据碎片和索引碎片,占用服务器存储空间和影响索引的效率。

mysql引擎:

          MyISAM引擎: 数据储存在MYD文件中,索引储存在MYI文件中

          InnoDB引擎:frm文件存储表结构,idb文件储存索引和数据

数据碎片优化步骤

查看ide库下需要优化的相关表sql:

select table_name,data_free from information_schema.tables where table_schema='ide' order by a.data_free desc;可以看到每个表的数据碎片分别是多少,如图所示:

1

我们可以看到:rdos_engine_job_cache表的数据碎片比较多,可以清理一下

查看清理前表相关文件的大小,数据和索引文件是49452,如图所示:

2

也可以用sql查询:数据大小如上上图的data_length,和data_free之和。

索引大小:show index from rdos_engine_job_cache;

Cardinality:索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。

相关字段值老铁们可以自行百度。

注意:在OPTIMIZE TABLE运行过程中,MySQL会锁定表。

对于myisam可以直接使用 optimize table table.name, 当是InnoDB引擎时,会报“Table does not support optimize, doing recreate + analyze instead”,一般情况下,由myisam转成innodb,会用alter table table.name engine='innodb'进行转换,优化也可以用这个。所以当是InnoDB引擎时我们就用alter table table.name engine='innodb'来代替optimize做优化就可以。

我们的表用的是Innodb引擎,执行命令:alter table rdos_engine_job_cache engine='innodb';如图所示:

由图可以看到清理前后的对比:表空间确实释放了不少

索引碎片优化步骤

Analyze Table 

MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为“散列程度”),它表示某个索引对应的列包含多少个不同的值——如果cardinality大大少于数据的实际散列程度,那么索引就基本失效了。 
我们可以使用SHOW INDEX语句来查看索引的散列程度: 

SHOW INDEX FROM PLAYERS; 

TABLE   KEY_NAME COLUMN_NAME CARDINALITY 
------- -------- ----------- ----------- 
PLAYERS PRIMARY PLAYERNO             14 

因为此时PLAYER表中不同的PLAYERNO数量远远多于14,索引基本失效。 
下面我们通过Analyze Table语句来修复索引: 

ANALYZE TABLE PLAYERS; 
SHOW INDEX FROM PLAYERS; 
结果是: 
TABLE   KEY_NAME COLUMN_NAME CARDINALITY 
------- -------- ----------- ----------- 
PLAYERS PRIMARY PLAYERNO           1000 

此时索引已经修复,查询效率大大提高。 

需要注意的是,如果开启了binlog,那么Analyze Table的结果也会写入binlog,我们可以在analyze和table之间添加关键字local取消写入。 

猜你喜欢

转载自blog.csdn.net/qq_37191371/article/details/109388345