MySQL的analyze table和optimize table对表进行定期优化
1、analyze table优化表的统计信息
mysql> show index from t;
+-------+------------+---------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+-------+------------+---------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| t | 0 | PRIMARY | 1 | id | A | 1045625 | NULL | NULL | | BTREE | | | YES | NULL |
| t | 1 | idx_dept | 1 | dept | A | 9 | NULL | NULL | | BTREE | | | YES | NULL |
| t | 1 | idx_create_time | 1 | create_time | A | 1031590 | NULL | NULL | | BTREE | | | YES | NULL |
| t | 1 | idx_last_login_time | 1 | last_login_time | A | 1041290 | NULL | NULL | YES | BTREE | | | YES | NULL |
+-------+------------+---------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
4 rows in set (0.06 sec)
mysql> select count(1) from t_log_iteminfo;
+----------+
| count(1) |
+----------+
| 2262731 |
+----------+
1 row in set (0.80 sec)
mysql>mysql> show index from t_log_iteminfo;
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t_log_iteminfo | 1 | AK_Key_1 | 1 | id | A | 5095731 | NULL | NULL | | BTREE | | |
| t_log_iteminfo | 1 | Index_1 | 1 | CurrentDate | A | 1201908 | NULL | NULL | | BTREE | | |
| t_log_iteminfo | 1 | Index_1 | 2 | UserId | A | 1775250 | NULL | NULL | | BTREE | | |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
很明显,t_log_iteminfo全表才226万数据,但主键的索引基数居然有509万,说明统计信息不准确了,有必要对表进行analyze来更新表的统计信息,以使执行计划能更准确。
analyze的语法如下:
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
默认执行analyze是会记录binlog,如果不想记录binlog,可加上NO_WRITE_TO_BINLOG参数或LOCAL参数,LOCAL参数是NO_WRITE_TO_BINLOG参数的别名,就是更好记点,两个参数效果是一样的。
值得注意的是,使用ANALYZE TABLE分析表的过程中,数据库系统会对表加一个只读锁。在分析期间,只能读取表中的记录,不能更新和插入记录。ANALYZE TABLE语句能够分析InnoDB和MyISAM类型的表。
mysql> analyze no_write_to_binlog table t_log_iteminfo;
+---------------------+---------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------------------+---------+----------+----------+
| game.t_log_iteminfo | analyze | status | OK |
+---------------------+---------+----------+----------+
1 row in set (0.05 sec)
mysql>
mysql> show index from t_log_iteminfo;
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| t_log_iteminfo | 1 | AK_Key_1 | 1 | id | A | 2252847 | NULL | NULL | | BTREE | | |
| t_log_iteminfo | 1 | Index_1 | 1 | CurrentDate | A | 415329 | NULL | NULL | | BTREE | | |
| t_log_iteminfo | 1 | Index_1 | 2 | UserId | A | 382967 | NULL | NULL | | BTREE | | |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)
执行analyze后,主键的索引基数由原来的509万降到225万,和表记录数226万很接近了,说明统计信息更新正确。
2、optimize table对表进行碎片整理
OPTIMIZE TABLE重新组织表数据和关联索引数据的物理存储,以减少存储空间并提高访问表时的I / O效率。通俗点理解就是碎片整理。它会重建表以更新索引统计信息,因此执行optimize就没必要再执行analyze table了。
我们继续分析t_log_iteminfo表的情况:
mysql> show table status like 't_log_iteminfo'\G
*************************** 1. row ***************************Name: t_log_iteminfoEngine: InnoDBVersion: 10Row_format: DynamicRows: 2252847Avg_row_length: 78Data_length: 176373760
Max_data_length: 0Index_length: 158449664Data_free: 495976448Auto_increment: 71789430Create_time: 2018-12-30 03:46:06Update_time: 2020-04-01 02:08:35Check_time: NULLCollation: utf8_general_ciChecksum: NULLCreate_options: Comment: 操作日志
1 row in set (0.00 sec)
通过查看表状态可见,Data_free是495976448(也就是495976448/1024/1024=473MB),它比Data_length + Index_length还有大。
我们先解释下Data_length 和Index_length。从字面上直译就是“数据长度”和“索引长度”,直译的意思也很明显了,我们知道,一个表占用的磁盘空间,主要是由数据和索引构成的,在MyISAM里,数据和索引是分开两个文件存储的,在InnoDB里则是存放在相同的ibd文件里,在MySQL 8.0里,InnoDB的frm文件也取消了,把表结构也一起放在ibd文件里实现了原子性ddl。看官注意此处是“原子性ddl”,而不是“事务性ddl”,MySQL 8.0还是不支持打开一个事务,然后drop一张表,然后还想rollback这骚操作。
上面一段句总结就是 “表大小(单位MB)= (Data_length + Index_length)/1024/1024”(不要问我为什么要除两次1024,拒绝回答这样的问题)。我再看t_log_iteminfo表,通过上面公式计算的结果约等于319MB,但Data_free却有473MB,说明碎片很多了。简单点理解,Data_free就是碎片的多少(虽然严格来说不能完全这样理解)。
我们确定了表有很多碎片,则可以使用optimize来进行碎片整理,语法如下:
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE tbl_name [, tbl_name] ...
默认执行optimize是会记录binlog,如果不想记录binlog,可加上NO_WRITE_TO_BINLOG参数或LOCAL参数,LOCAL参数是NO_WRITE_TO_BINLOG参数的别名,就是更好记点,两个参数效果是一样的。
使用optimize table碎片整理过程中,数据库系统会对表进行锁这下,因此一定要注意要在数据库不繁忙时执行。
mysql> optimize local table t_log_iteminfo;
+----------------------------------+----------+----------+-------------------------------------------------------------------+
| Table | Op | Msg_type | Msg_text |
+----------------------------------+----------+----------+-------------------------------------------------------------------+
| db_log_fxhf_00813.t_log_iteminfo | optimize | note | Table does not support optimize, doing recreate + analyze instead |
| db_log_fxhf_00813.t_log_iteminfo | optimize | status | OK |
+----------------------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (12.10 sec)mysql> show table status like 't_log_iteminfo'\G
*************************** 1. row ***************************Name: t_log_iteminfoEngine: InnoDBVersion: 10Row_format: DynamicRows: 2253722Avg_row_length: 89Data_length: 200998912
Max_data_length: 0Index_length: 106086400Data_free: 4194304Auto_increment: 71789835Create_time: 2020-04-01 02:24:52Update_time: 2020-04-01 02:25:44Check_time: NULLCollation: utf8_general_ciChecksum: NULLCreate_options: Comment: 操作日志
1 row in set (0.00 sec)
可以看到Data_free由原来的473MB缩小到现在的4194304字节(即4MB),回收了不少空间。
上面执行optimize时可以看到“Table does not support optimize, doing recreate + analyze instead”,说明InnoDB是通过重建表加analyze方式来代替optimize table操作的。
没必要每天执行optimize table,可以根据实际碎片产生的情况来制定相应的维护计划,例如每月一次,或者每季度一次,或者每半年一次等。
MySQL的analyze table和optimize table对表进行定期优化相关推荐
- 小白学习MySQL - InnoDB支持optimize table?
MySQL数据库中进行表空间整理,可以用的一种操作就是optimize table, OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL]TABLE tbl_name [, tb ...
- mysql进阶:optimize table 优化表命令 Table does not support optimize, doing recreate + analyze instead
optimize table table_name 1. 问题描述 在使用mysql的时候有时候,可能会发现尽管一张表删除了许多数据,但是这张表表的数据文件和索引文件却奇怪的没有变小.这是因为mysq ...
- MySQL check table/optimize table/analyze table/REPAIR TABLE
check table:检查InnoDB和MyIsam是否有错误.检查表或者视图是否存在错误,对 MyISAM 和 InnoDB 存储引擎的表有作用.对于 MyISAM 存储引擎的表进行表检查,也会同 ...
- mysql optimize 作用_mysql optimize table
mysql 数据文件的使用是只扩展,不回收.对表执行delete之后,磁盘上数据文件是不会缩小的. 通常的做法,是先逻辑导出,然后truncate 原表(或者删除重建),再导入. 另外还有一种方法是o ...
- optimize table、analyze table、alter table、gh-ost
MySQL系列 第一章:sql_mode模式 第二章:optimize table.analyze table.alter table.gh-ost 文章目录 MySQL系列 一.alter tabl ...
- MySQL 中ANALYZE [LOCAL NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 本语句用于分析和存储表的关键字分布.在分析期间,使用一个读取锁 ...
- optimize table优化mysql例子
原始数据 数据量 mysql> select count(*) as total from ad_visit_history; +---------+ | total | +-------- ...
- mysql之 OPTIMIZE TABLE整理碎片
来看看手册中关于 OPTIMIZE 的描述: OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ... 如果您已经删除 ...
- MySql 杂记 之OPTIMIZE TABLE操作
1:MySQL OPTIMIZE TABLE操作 MySQL官方建议不要经常(每小时或每天)进行碎片整理,一般根据实际情况,只需要每周或者每月整理一次即可,可以写成定时任务来做,这是因为3在OPTIM ...
最新文章
- 【Linux】服务器常用的操作命令
- jquery ui 自動完成對中文字搜尋Bug(firefox)
- struts+hibernate+oracle+easyui实现lazyout组件的简单案例——Emp实体类和对应的配置信息
- [再寄小读者之数学篇](2014-04-22 平方差公式在矩阵中的表达)
- python找出录取率最高的年份_Python分析42年高考数据,告诉你高考为什么这么难?...
- 【文文殿下】[BZOJ4008] [HNOI2015] 亚瑟王
- 09 spring-aop
- Docker生产环境配置——设置direct-lvm模式
- 125KHz 100cm ID 读卡电路_NX系列PLC-NX-ID数字输入单元_欧姆龙继电器_欧姆龙PLC_欧姆龙接近开关...
- C/C++求职者必备的20道面试题
- easyUI1.7学习第一天_menu表单
- 全球及中国吊链总成行业研究及十四五规划分析报告
- matlab熵权法,matlab—熵权法
- 5G基站到底长啥样?和4G有啥区别?
- mysql sysdatabases_未能在 sysdatabases 中找到数据库 aa1xxxx 所对应的条目。没有找到具有该名称的条目...
- java实现Excel动态列导出的简单例子
- java录入学生信息_java实现学生成绩录入系统
- Boosting(一)
- python 做网站 知乎_python做网站 知乎的搜索结果-阿里云开发者社区
- 高数值孔径(NA=0.68)聚焦透镜焦点区域激光光束的模拟
热门文章
- Hadoop实现数据清洗ETL
- 阿里云公布 “抄袭事件” 调查结果:确有员工违规
- 社会,经济的1000+篇文章总结
- openfire html5,HTML5来了,7个混合式移动开发框架
- JixiPix Hand Tint Pro for Mac(图片处理软件)
- 关于uniapp编译小程序 引入全局scss问题解决方案
- 圣诞树太俗气,圣诞牛才够创意----阿里巴巴B2B高上大玩法的启示
- 抖音SEO,抖音SEO搜索排名详细介绍
- Idea导包正确还是显示标红(错误)
- excel怎么批量添加单位平方米㎡