转载自:http://www.cnblogs.com/shawnloong/archive/2013/02/07/2908911.html

OPTIMIZE TABLE 当您的库中删除了大量的数据后,您可能会发现数据文件尺寸并没有减小。这是因为删除操作后在数据文件中留下碎片所致。OPTIMIZE TABLE 是指对表进行优化。如果已经删除了表的一大部分数据,或者如果已经对含有可变长度行的表(含有 VARCHAR 、 BLOB 或 TEXT 列的表)进行了很多更改,就应该使用 OPTIMIZE
TABLE 命令来进行表优化。这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费 。OPTIMIZE TABLE
命令只对 MyISAM 、 BDB 和 InnoDB 表起作用 。表优化的工作可以每周或者每月定期执行,对提高表的访问效率有一定的好处,但是需要注意的是,优化表期间会锁定表,所以一定要安排在空闲时段进行。

一,原始数据

 
  1. mysql> select count(*) as total from ad_visit_history;
  2. +---------+
  3. | total   |
  4. +---------+
  5. | 1187096 |                      //总共有118万多条数据
  6. +---------+
  7. 1 row in set (0.04 sec)

2,存放在硬盘中的表文件大小

 
  1. [root@BlackGhost test1]# ls |grep visit |xargs -i du {}
  2. 382020    ad_visit_history.MYD                    //数据文件占了380M
  3. 127116    ad_visit_history.MYI                     //索引文件占了127M
  4. 12    ad_visit_history.frm                              //结构文件占了12K

3,查看一下索引信息

 
  1. mysql> show index from ad_visit_history from test1;     //查看一下该表的索引信息
  2. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  3. | Table            | Non_unique | Key_name          | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
  4. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  5. | ad_visit_history |          0 | PRIMARY           |            1 | id            | A         |     1187096 |     NULL | NULL   |      | BTREE      |         |
  6. | ad_visit_history |          1 | ad_code           |            1 | ad_code       | A         |          46 |     NULL | NULL   | YES  | BTREE      |         |
  7. | ad_visit_history |          1 | unique_id         |            1 | unique_id     | A         |     1187096 |     NULL | NULL   | YES  | BTREE      |         |
  8. | ad_visit_history |          1 | ad_code_ind       |            1 | ad_code       | A         |          46 |     NULL | NULL   | YES  | BTREE      |         |
  9. | ad_visit_history |          1 | from_page_url_ind |            1 | from_page_url | A         |       30438 |     NULL | NULL   | YES  | BTREE      |         |
  10. | ad_visit_history |          1 | ip_ind            |            1 | ip            | A         |      593548 |     NULL | NULL   | YES  | BTREE      |         |
  11. | ad_visit_history |          1 | port_ind          |            1 | port          | A         |       65949 |     NULL | NULL   | YES  | BTREE      |         |
  12. | ad_visit_history |          1 | session_id_ind    |            1 | session_id    | A         |     1187096 |     NULL | NULL   | YES  | BTREE      |         |
  13. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  14. 8 rows in set (0.28 sec)

索引信息中的列的信息说明。

Table :表的名称。 Non_unique :如果索引不能包括重复词,则为0。如果可以,则为1。 Key_name :索引的名称。 Seq_in_index :索引中的列序列号,从1开始。 Column_name :列名称。 Collation :列以什么方式存储在索引中。在MySQLSHOW
INDEX语法中,有值’A’(升序)或NULL(无分类)。 Cardinality :索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk
-a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。 Sub_part :如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。 Packed :指示关键字如何被压缩。如果没有被压缩,则为NULL。 Null :如果列含有NULL,则含有YES。如果没有,则为空。 Index_type :存储索引数据结构方法(BTREE,
FULLTEXT, HASH, RTREE)

二,删除一半数据

 
  1. mysql> delete from ad_visit_history where id>598000;          //删除一半数据
  2. Query OK, 589096 rows affected (4 min 28.06 sec)
  3. [root@BlackGhost test1]# ls |grep visit |xargs -i du {}              //相对应的MYD,MYI文件大小没有变化
  4. 382020    ad_visit_history.MYD
  5. 127116    ad_visit_history.MYI
  6. 12    ad_visit_history.frm

按常规思想来说,如果在数据库中删除了一半数据后,相对应的.MYD,.MYI文件也应当变为之前的一半。但是删除一半数据后,.MYD.MYI尽然连1KB都没有减少 ,这是多么的可怕啊。

我们在来看一看,索引信息

Mysql> show index from ad_visit_history;    
  1. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  2. | Table            | Non_unique | Key_name          | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
  3. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  4. | ad_visit_history |          0 | PRIMARY           |            1 | id            | A         |      598000 |     NULL | NULL   |      | BTREE      |         |
  5. | ad_visit_history |          1 | ad_code           |            1 | ad_code       | A         |          23 |     NULL | NULL   | YES  | BTREE      |         |
  6. | ad_visit_history |          1 | unique_id         |            1 | unique_id     | A         |      598000 |     NULL | NULL   | YES  | BTREE      |         |
  7. | ad_visit_history |          1 | ad_code_ind       |            1 | ad_code       | A         |          23 |     NULL | NULL   | YES  | BTREE      |         |
  8. | ad_visit_history |          1 | from_page_url_ind |            1 | from_page_url | A         |       15333 |     NULL | NULL   | YES  | BTREE      |         |
  9. | ad_visit_history |          1 | ip_ind            |            1 | ip            | A         |      299000 |     NULL | NULL   | YES  | BTREE      |         |
  10. | ad_visit_history |          1 | port_ind          |            1 | port          | A         |       33222 |     NULL | NULL   | YES  | BTREE      |         |
  11. | ad_visit_history |          1 | session_id_ind    |            1 | session_id    | A         |      598000 |     NULL | NULL   | YES  | BTREE      |         |
  12. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  13. 8 rows in set (0.00 sec)

对比一下,这次索引查询和上次索引查询,里面的数据信息基本上是上次一次的一本,这点还是合乎常理。

三,用optimize table来优化一下

Java代码  
  1. mysql> optimize table ad_visit_history;                                             //删除数据后的优化
  2. +------------------------+----------+----------+----------+
  3. | Table                  | Op       | Msg_type | Msg_text |
  4. +------------------------+----------+----------+----------+
  5. | test1.ad_visit_history | optimize | status   | OK       |
  6. +------------------------+----------+----------+----------+
  7. 1 row in set (1 min 21.05 sec)

1,查看一下.MYD,.MYI文件的大小

 
  1. [root@BlackGhost test1]# ls |grep visit |xargs -i du {}
  2. 182080    ad_visit_history.MYD                                          //数据文件差不多为优化前的一半
  3. 66024    ad_visit_history.MYI                                             //索引文件也一样,差不多是优化前的一半
  4. 12    ad_visit_history.frm

2,查看一下索引信息

mysql> show index from ad_visit_history;    
  1. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  2. | Table            | Non_unique | Key_name          | Seq_in_index | Column_name   | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
  3. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  4. | ad_visit_history |          0 | PRIMARY           |            1 | id            | A         |      598000 |     NULL | NULL   |      | BTREE      |         |
  5. | ad_visit_history |          1 | ad_code           |            1 | ad_code       | A         |          42 |     NULL | NULL   | YES  | BTREE      |         |
  6. | ad_visit_history |          1 | unique_id         |            1 | unique_id     | A         |      598000 |     NULL | NULL   | YES  | BTREE      |         |
  7. | ad_visit_history |          1 | ad_code_ind       |            1 | ad_code       | A         |          42 |     NULL | NULL   | YES  | BTREE      |         |
  8. | ad_visit_history |          1 | from_page_url_ind |            1 | from_page_url | A         |       24916 |     NULL | NULL   | YES  | BTREE      |         |
  9. | ad_visit_history |          1 | ip_ind            |            1 | ip            | A         |      598000 |     NULL | NULL   | YES  | BTREE      |         |
  10. | ad_visit_history |          1 | port_ind          |            1 | port          | A         |       59800 |     NULL | NULL   | YES  | BTREE      |         |
  11. | ad_visit_history |          1 | session_id_ind    |            1 | session_id    | A         |      598000 |     NULL | NULL   | YES  | BTREE      |         |
  12. +------------------+------------+-------------------+--------------+---------------+-----------+-------------+----------+--------+------+------------+---------+
  13. 8 rows in set (0.00 sec)

从以上数据我们可以得出,ad_code,ad_code_ind,from_page_url_ind等索引机会差不多都提高了85%,这样效率提高了好多。

四,小结

结合mysql官方网站的信息,个人是这样理解的。当你删除数据 时,mysql并不会回收,被已删除数据的占据的存储空间,以及索引位。而是空在那里,而是等待新的数据来弥补这个空缺,这样就有一个缺少,如果一时半
会,没有数据来填补这个空缺,那这样就太浪费资源了。所以对于写比较频烦的表,要定期进行optimize,一个月一次,看实际情况而定了。

举个例子来说吧。有100个php程序员辞职了,但是呢只是人走了,php的职位还在那里,这些职位不会撤销,要等新的php程序来填补这些空位。招一个好的程序员,比较难。我想大部分时间会空在那里。哈哈。

五,手册中关于OPTIMIZE的一些用法和描述

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...

如果您已经删除了表的一大部分,或者如果您已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)进行了很多更改,则应使用 OPTIMIZE TABLE。被删除的记录被保持在链接清单中,后续的INSERT操作会重新使用旧的记录位置。您可以使用OPTIMIZE TABLE来重新 利用未使用的空间,并整理数据文件的碎片。

在多数的设置中,您根本不需要运行OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新,您也不需要经常运行,每周一次或每月一次 即可,只对特定的表运行。

OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。

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

最新文章

  1. Linux添加用户(user)到用户组(group)
  2. curl模拟登录新浪微博
  3. iOS socket TCP UDP
  4. 【Oozie】安装配置Oozie
  5. Java一些动手动脑实验
  6. sqoop的codegen工具
  7. java消息队列
  8. Shell中逻辑判断
  9. bzoj:3616: War
  10. 201621123060《JAVA程序设计》第十四周学习总结
  11. JAVA 第二天 关键字
  12. Android Hybrid App自动化测试实战讲解(基于python)
  13. 实用矩阵类(Matrix)(带测试)
  14. 设计模式之装饰模式(Decorator)摘录
  15. spring security文档地址
  16. Ubuntu中程序部署时无法加载动态库的解决方法
  17. Casual Note of Computer Network
  18. No mysqld or mysql.server after mariadb-server install
  19. lapis cockroachdb 数据访问试用
  20. 走了很多弯路的CCScrollView

热门文章

  1. 使用清华镜像在python中pip 安装
  2. Python3 下安装python-votesmart
  3. 关于C#中如何使用wmi获得操作系统信息?
  4. 普通Java类获取Spring的Bean的方法
  5. codeforces 319B Psychos in a Line(模拟)
  6. 一个项目的Makefile编写及调试
  7. 【Spring.Net】- 环境搭建
  8. [Redis]在Windows下的下载及安装
  9. Flink的序列化与flink-hadoop-compatibility
  10. wpf拖拽