Mysql Innodb 表碎片整理

一、为什么会产生碎片

简单的说,删除数据必然会在数据文件中造成不连续的空白空间,而当插入数据时,这些空白空间则会被利用起来.于是造成了数据的存储位置不连续,以及物理存储顺序与理论上的排序顺序不同,这种是数据碎片.实际上数据碎片分为两种,一种是单行数据碎片,另一种是多行数据碎片.前者的意思就是一行数据,被分成N个片段,存储在N个位置.后者的就是多行数据并未按照逻辑上的顺序排列.当有大量的删除和插入操作时,必然会产生很多未使用的空白空间,这些空间就是多出来的额外空间.索引也是文件数据,所以也会产生索引碎片,理由同上,大概就是顺序紊乱的问题.Engine 不同,OPTIMIZE 的操作也不一样的,MyISAM 因为索引和数据是分开的,所以 OPTIMIZE 可以整理数据文件,并重排索引。这样不但会浪费空间,并且查询速度也更慢。

二、Innodb 表碎片整理

1、查看表行数

1)行数

MariaDB [agent_platform]> select count(1) from corporationprofit_old;
+----------+
| count(1) |
+----------+
| 18198196 |
+----------+
1 row in set (54.35 sec)

2)所占磁盘大小

9218180KB

cat test.sh
a=`ls /u02/mysql/data/agent_platform/corporationprofit_old*|xargs  du|awk ‘{print $1}‘`
m=0
for i in $a
do
  echo $i
  ((m=$m+$i))
done
echo $m

3)查看表的信息

MariaDB [(none)]> select ROW_FORMAT,TABLE_ROWS,DATA_LENGTH,INDEX_LENGTH,MAX_DATA_LENGTH,DATA_FREE,ENGINE
    -> from information_schema.TABLES where TABLE_SCHEMA=‘agent_platform‘ and TABLE_NAME=‘corporationprofit_old‘ limit 1;
+------------+------------+-------------+--------------+-----------------+------------+--------+
| ROW_FORMAT | TABLE_ROWS | DATA_LENGTH | INDEX_LENGTH | MAX_DATA_LENGTH | DATA_FREE  | ENGINE |
+------------+------------+-------------+--------------+-----------------+------------+--------+
| Compact    |   17105657 |  5187551232 |   2068905984 |               0 | 1101004800 | InnoDB |
+------------+------------+-------------+--------------+-----------------+------------+--------+
1 row in set (0.25 sec)

2、删除部分数据

1)总共删除了8157318行

MariaDB [agent_platform]> delete from corporationprofit_old  where date_created>=‘2018-10-01‘ ;
Query OK, 8157318 rows affected (2 min 52.18 sec)

2)查看表的行数

MariaDB [agent_platform]> select count(1) from corporationprofit_old;
+----------+
| count(1) |
+----------+
| 10040878 |
+----------+
1 row in set (11.66 sec)

3)查看表的信息

MariaDB [agent_platform]> select ROW_FORMAT,TABLE_ROWS,DATA_LENGTH,INDEX_LENGTH,MAX_DATA_LENGTH,DATA_FREE,ENGINE
    -> from information_schema.TABLES where TABLE_SCHEMA=‘agent_platform‘ and TABLE_NAME=‘corporationprofit_old‘ limit 1;
+------------+------------+-------------+--------------+-----------------+------------+--------+
| ROW_FORMAT | TABLE_ROWS | DATA_LENGTH | INDEX_LENGTH | MAX_DATA_LENGTH | DATA_FREE  | ENGINE |
+------------+------------+-------------+--------------+-----------------+------------+--------+
| Compact    |    9779701 |  5360599040 |   2138177536 |               0 | 4380950528 | InnoDB |
+------------+------------+-------------+--------------+-----------------+------------+--------+
1 row in set (0.30 sec)

4)查看表删除后所占磁盘大小

9218180KB,没有改变

3、表数据碎片整理

1)表数据整理

MariaDB [agent_platform]> OPTIMIZE table corporationprofit_old;
+--------------------------------------+----------+----------+-------------------------------------------------------------------+
| Table                                | Op       | Msg_type | Msg_text                                                          |
+--------------------------------------+----------+----------+-------------------------------------------------------------------+
| agent_platform.corporationprofit_old | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| agent_platform.corporationprofit_old | optimize | status   | OK                                                                |
+--------------------------------------+----------+----------+-------------------------------------------------------------------+
2 rows in set (5 min 34.79 sec)

2)查看表信息

MariaDB [agent_platform]> select ROW_FORMAT,TABLE_ROWS,DATA_LENGTH,INDEX_LENGTH,MAX_DATA_LENGTH,DATA_FREE,ENGINE
    -> from information_schema.TABLES where TABLE_SCHEMA=‘agent_platform‘ and TABLE_NAME=‘corporationprofit_old‘ limit 1;
+------------+------------+-------------+--------------+-----------------+-----------+--------+
| ROW_FORMAT | TABLE_ROWS | DATA_LENGTH | INDEX_LENGTH | MAX_DATA_LENGTH | DATA_FREE | ENGINE |
+------------+------------+-------------+--------------+-----------------+-----------+--------+
| Compact    |    9863806 |  2996649984 |    854638592 |               0 |   6291456 | InnoDB |
+------------+------------+-------------+--------------+-----------------+-----------+--------+

3)产看整理后所占磁盘大小

3881468KB

碎片整理后,表的大小比之前减少了5GB。

原文地址:https://www.cnblogs.com/xibuhaohao/p/10216078.html

时间: 2024-10-20 07:39:24

Mysql Innodb 表碎片整理的相关文章

MySQL数据表碎片整理

在MySQL中,我们经常会使用VARCHAR.TEXT.BLOB等可变长度的文本数据类型.不过,当我们使用这些数据类型之后,我们就不得不做一些额外的工作--MySQL数据表碎片整理. 那么,为什么在使用这些数据类型之后,我们就要对MySQL定期进行碎片整理呢? 现在,我们先来看一个具体的例子.在这里,我们使用如下SQL语句在MySQL自带的TEST数据库中创建名为DEMO的数据表并插入5条测试数据. --创建DEMO表  id int unsigned,  body text  ) engine

MySQL关于表碎片整理OPTIMIZE TABLE操作

MySQL关于表碎片整理OPTIMIZE TABLE操作的官方建议1.MySQL官方建议不要经常(每小时或每天)进行碎片整理,一般根据实际情况,只需要每周或者每月整理一次即可,可以写成定时任务来做.2.OPTIMIZE TABLE只对MyISAM,BDB和InnoDB表起作用,尤其是MyISAM表的作用最为明显.此外,并不是所有表都需要进行碎片整理,一般只需要对包含上述可变长度的文本数据类型的表进行整理即可.3.在OPTIMIZE TABLE运行过程中,MySQL会锁定表.4.默认情况下,直接对

MySQL InnoDB表--BTree基本数据结构

MySQL InnoDB表是索引组织表这一点应该是每一个学习MySQL的人都会首先学到的知识,这代表这表中的数据是按照主键顺序存储,也就是说BTree的叶子节点存储了所有该行的数据. 我最开始是搞Oracle的,头一次接触MySQL的时候,默认引擎还是MyISAM.当时我看到公司建立的所有的InnoDB表都会在第一列加一个业务无关的自增主键,我觉得很没有必要,问了些人这么做的意义,得到的答案也是让人搞不懂,其实也都没有说到根本上,只是说这样据说效率会更好.于是我在数据仓库项目的建设时普遍没有采用

关于MySQL InnoDB表的二级索引是否加入主键列的问题解释

关于MySQL InnoDB表的二级索引是否加入主键,总结如下: 1对于MySQL InnoDB表的二级索引是否加入主键,官方也有明确的说明,建议线上MySQL的二级索引创建时强制加入主键所有的列,可以做到所有的MySQL 版本统一. 2.MySQL 5.6.9之前,InnoDB引擎层是会对二级索引做自动扩展,但是优化器不能识别出扩展的主键. 3.MySQL 5.6.9开始InnoDB引擎层是会对二级索引做自动扩展,优化器能识别出扩展的主键. 4.索引的大小一样,二级索引有没有加入主键列,在In

mysql innodb表分区

分区的一些优点包括:      1).与单个磁盘或文件系统分区相比,可以存储更多的数据.      2).对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的分区,很容易地删除那些数据.相反地,在某些情况下,添加新数据的过程又可以通过为那些新数据专门增加一个新的分区,来很方便地实现.通常和分区有关的其他优点包括下面列出的这些.MySQL分区中的这些功能目前还没有实现,但是在我们的优先级列表中,具有高的优先级:我们希望在5.1的生产版本中,能包括这些功能.      3).一些查询可以

关于Oracle表碎片整理

数据库在日常使用过程中,不断的insert,delete,update操作,导致表和索引出现碎片是在所难免的事情,碎片多了,sql的执行效率自然就差了,道理很简单,高水位线(HWL)下的许多数据块都是无数据的,但全表扫描的时候要扫描到高水位线的数据块,也就是说oracle要做许多的无用功!因此oracle提供了shrink space碎片整理功能.对于索引,可以采取rebuild online的方式进行碎片整理,一般来说,经常进行DML操作的对象DBA要定期进行维护,同时注意要及时更新统计信息!

使用参数innodb_file_per_table支持MySQL InnoDB表数据共享空间自动收缩

http://heylinux.com/archives/2367.html http://blog.csdn.net/ywh147/article/details/8996022 使用过MySQL的同学,刚开始接触最多的莫过于MyISAM表引擎了,这种引擎的数据库会分别创建三个文件:表结构.表索引.表数据空间.我们可以将某个数据库目录直接迁移到其他数据库也可以正常工作.然而当你使用InnoDB的时候,一切都变了.InnoDB 默认会将所有的数据库InnoDB引擎的表数据存储在一个共享空间中:i

MySQL Innodb表导致死锁日志情况分析与归纳

发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志 案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志.两个sql语句如下:(1)insert into backup_table select * from source_table(2)DELETE FROM source_table WHERE Id>5 AND titleWeight<32768 AND

mysql innodb表 utf8 gbk占用空间相同,毁三观

昨天因为发生字符集转换相关错误,今天想验证下utf8和gbk中英文下各自空间的差距.这一测试,绝对毁三观,无论中文还是中文+英文,gbk和utf8占用的实际物理大小完全相同,根本不是理论上所述的“UTF-8对中文采用3个字节,对英文采用1个字节,GBK对中英文都采用2个字节”,如下所示: 空表: GBK如下: CREATE TABLE `test_char_gbk` ( `gbk_str` varchar(100) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHA