MySQL提供了分析表、检查表和优化表的语句。分析表主要是分析关键字的分布,检查表主要是检查表是否存在错误,优化表主要是消除删除或者更新造成的空间浪费。

【1】分析表

MySQL中提供了 ANALYZE TABLE 语句分析表,analyze table 语句的基本语法如下:

analyze [local | no_write_to_binlog] table table_name[,tbl_name]....

默认的,MySQL服务会将analyze table语句写到binlog中,以便在主从架构中,从服务能够同步数据。可以添加参数 local 或者 no_write_to_binlog 取消将语句写到binlog中。

使用 analyze table 分析表的过程中,数据库系统会自动对表加一个 只读锁。 在分析期间,只能读取表中的记录,不能更新和插入记录。analyze table 语句能够分析 InnoDB和MyISAM类型的表,但是不能作用于视图。

analyze table分析后的统计结果会反映到 cardinality 的值,该值统计了表中某一键所在的列不重复的值的个数。 该值越接近表中的总行数,则在表连接查询或者索引查询时,就越优先被优化器选择使用。也就是索引列的 cardinality 的值与表中数据的总条数差距越大,即使查询的时候使用了该索引作为查询条件,存储引擎实际查询的时候使用的概率就越小。

下面通过例子来验证一下,cardinality 可以通过 show index from table_name 查看。

CREATE TABLE `user1` (`id` int NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`age` int DEFAULT NULL,`sex` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),KEY `idx_name` (`name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb3;

创建表user1,并插入1000条数据,其中name值均为jane 。此时我们执行 SHOW INDEX FROM user1;

如上图所示,Cardinality 列 对于id 是12(其实应该是1000),对于name是1(实际就是1)。我们使用分析表语句 后再次查看:


上面结果显示的信息说明如下:

  • Table:表示分析的表的名称
  • Op:表示执行的操作。analyze表示进行分析操作
  • Msg_type:表示信息类型,其值通常是状态(status)、信息(info)、注意(note)、警告(warning)和错误(error)之一。
  • Msg_text:显示信息。

此时再次查看user表的 Cardinality,如下所示:

SHOW INDEX FROM user1;


可以看到id主键的Cardinality已经修正,和数据总量一致,此时索引已经修复,查询效率大大提高。这个值只要大致相同就表示索引被优化器使用的概率就越大。


我们修改id=2的name值,然后再次分析查看,可以看到Cardinality列已经从 1 变成了 2:

# 修改值
update user1 set name='janus' where id=2;
# 查看索引
SHOW INDEX FROM user1;
# 分析表
analyze table user1;
# 查看索引
SHOW INDEX FROM user1;


我们查看下面SQL的执行计划:

explain select * from user1 where name='jane'

结果如下所示,可以看到虽然name字段上面有索引,但是执行计划中显示type为’ALL’,表示并没有使用到索引。

我们再看下面SQL的执行计划:

explain select * from user1 where name='janus'

结果如下所示,可以看到确实是用到了索引,检索的行数rows为1。

这两个SQL也说明了:

  • 如果取值离散度太小,那么不太适合创建索引
  • 如果创建了索引,那么查询“索引取值少量数据”时才会用到索引

【2】检查表

MySQL中可以使用 CHECK TABLE语句来检查表。CHECK TABLE语句能够检查InnoDBMyISAM类型的表是否存在错误。 CHECK TABLE语句在执行过程中也会给表加上只读锁

对于MyISAM类型的表,CHECK TABLE 语句还会更新关键字统计数据。而且 CHECK TABLE也可以检查视图是否有错误,比如在视图定义中被引用的表已不存在。

该语句的基本语法如下:

CHECK TABLE table_name[, table_name] ....[option]...
option={QUICK | FAST | MEDIUM | EXTENDED |CHANGED }

option各个选项的意义分别是:

  • QUICK:不扫描行,不检查错误的连接
  • FAST:只检查没有被正确关闭的表
  • CHANGED:只检查上次检查后被更改的表和没有被正确关闭的表
  • MEDIUM:扫描行,以验证被删除的连接是有效的。也可以计算各行的关键字校验和,并使用计算出的校验和验证这一点。
  • EXTENDED:对每行的所有关键字进行一个全面的关键字查找。这可以确保表时100%一致的,但是花的时间较长。

option只对MyISAM类型的表有效,对InnoDB类型的表无效。比如:

check table user1


该语句对于检查的表可能会产生多行信息。最后一行有一个状态的Msg_type值 ,Msg_text通常为OK。如果得到的不是OK,通常要对其进行修复;是OK说明表已经是最新的了。表已经是最新的,意味着存储引擎对这张表不必进行检查。

【3】优化表

① OPTIMIZE TABLE

MySQL中使用optimize table语句来优化表。但是,optimize table语句只能优化表中的varchar、blob或text类型的字段。一个表使用了这些字段的数据类型,若已经删除了表的一大部分数据,或者已经对含有可变长度行的表(含有varchar、blob或text列的表)进行了很多更新,则应使用optimize table来重新利用未使用的空间,并整理数据文件的碎片。

optimize table语句对InnoDB和MyISAM类型的表都有效。该语句在执行过程中也会给表加上只读锁。optimize table语句的基本语法如下:

optimize [local | no_write_to_binlog] table table_name [,table_name]...

local | no_write_to_binlog 关键字的意义和分析表相同,都是指定不写入二进制日志。

如下所示,我们在user1中插入十万条数据,占用空间如下:


如下所示,我们删除一半数据,再次查看该文件,发现占用大小并未改变

delete from user1 where id>50000


优化表之后再次查看,发现文件占用空间变小:

optimize table user1;


上图(优化结果示意图)是正常的,针对MySQL的InnoDB引擎,optimize结果就是那样的(官网有说明)。在MyISAM中,是先分析这张表,然后会整理相关的MySQL datafile,之后回收未使用的空间。在InnoDB中,回收空间是简单通过alter table 进行整理空间。在优化期间,MySQL会创建一个临时表,优化完成之后会删除原始表,然后会将临时表rename成为原始表。

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

② mysqlcheck

mysqlcheck -o DatabaseName tableName -uroot -p******

mysqlcheck是Linux中的rompt,-o是代表Optimize。

举例:优化所有表:

mysqlcheck -o DatabaseName -u root -p****
# 或
mysqlcheck -o --all-databases -u root -p****

MySQL中的分析表、检查表与优化表如何操作?相关推荐

  1. MYSQL 分析表、检查表和优化表

    1. 对表进行优化 ( 优化表主要作用是消除删除或者更新造成的空间浪费) 2. 对表进行分析(分析关键字的分布, 分析并存储MyISAM和BDB表中键的分布) 3. 对表进行检查(检查表的错误,并且为 ...

  2. mysql数据库优化课程---15、mysql优化步骤(mysql中最常用最立竿见影的优化是什么)...

    mysql数据库优化课程---15.mysql优化步骤(mysql中最常用最立竿见影的优化是什么) 一.总结 一句话总结:索引优化最立竿见影 索引优化:不然有多少行要扫描多少次,1亿行大概是5到10分 ...

  3. 不同服务器数据库表连接查询修改,如何连接多个数据库,mysql中的服务器和查询两个表中的对方?...

    我期待从不同服务器连接两个不同的数据库.此外,我想运行一个查询,从两个数据库中获取数据到一个单一的结果.我正在使用mysql在PHP脚本中执行此操作.这里是如何很期待做[没有成功:)]如何连接多个数据 ...

  4. mysql中递增列_如何使用JDBC在MySQL中创建带有自动递增列的表?

    在创建表时,在某些情况下,我们需要自动生成/增加列的值(例如ID).各种数据库以不同的方式支持此功能. 在MySQL数据库中,您可以使用以下语法声明列自动递增.CREATE TABLE table_n ...

  5. 用MySql的查询分析语法explain来优化查询和索引

    http://hi.baidu.com/wtnzone/item/beb83840a4971af4dd0f6c77 数据库最常见的操作就是查询了,我们经常要用"SELECT"语法对 ...

  6. MySQL中关于insert语句速度的优化

    1.分析 插入一行分下面几个动作,括号后面是其大约比例额 Connecting(3) Sendint query to server(2) Parsing query(2) Inserting row ...

  7. php explain type等级,mysql中explain分析sql详解

    Explain举例mysql> explain select * from event; +--+-----+---+--+-----+--+---+--+--+---+ | id | sele ...

  8. MYSQL中RAND子句的使用_mysql优化--rand()优化

    众所周知,在mysql中,随机的取10条数据,如:select * from users order by rand() limit 10,效果非常差,因为会多次的执行,如果等值查询用rand()也是 ...

  9. mysql中如何删除空记录表_mysql删除表中的记录

    大家都知道,在MySQL中删除一个表中的记录有两种方法,一种是DELETE FROM TABLENAME WHERE... , 还有一种是TRUNCATE TABLE TABLENAME. DELET ...

最新文章

  1. 浅析pinyin4j源码 简单利用pinyin4j对中文字符进行自然排序(转)
  2. ue4加载本地版本_【虚幻4】创建本地数据库
  3. xml 属性value换行显示_python 标准库之xml.etree.ElementTree
  4. php去字符串空格,php怎么去掉字符串中空格
  5. VS.NET 2003 安装问题
  6. 简单文件传输TFTP服务器搭建 Linux RHEL6
  7. 光纤终端服务器,[原创]简单介绍光缆终端盒知识
  8. 一套完整的Selenium自动化测试框架设计实战,这次38K, 妥了
  9. MySQL 可以用localhost 连接,但不能用IP连接的问题,局域网192.168.*.* 无法连接mysql...
  10. RocketMQ源码解析-PullConsumer取消息(1)
  11. 大数据分析有几种方法
  12. maven私服的创建和使用
  13. 入门云计算要学习掌握哪些技术?
  14. python制作简单网页_用python制作简单网页
  15. linux系统scsi硬盘,Linux系统中SCSI硬盘的热拔插
  16. 六款最佳、免费的网络延迟测试工具
  17. 智能合约逆向心法1(案例篇)——34C3_CTF题目分析
  18. echarts地图 自定义区域
  19. 德鲁克《卓有成效的管理者》学习笔记-掌握时间的学习和实践
  20. 完美解决安装MySQL Install/Remove of the Service Denied!错误解决办法

热门文章

  1. 鸿蒙OS Hi3861的芯片实际开发中遇到的问题
  2. 360黑匣子之谜——奇虎360“癌”性基因大揭秘
  3. 个人笔记-SpringMVC请求,数组类型参数传参
  4. php京东秒杀,js实现京东秒杀倒计时功能
  5. 高性能图表控件LightningChart中Datagrid的Pasar datos deview闪电图问题解答
  6. 小觅双目摄像头如何加速外卖无人配送新时代
  7. 内网https需要ssl证书_IP地址可以申请SSL证书/https证书吗?
  8. 地球的“3D大片”来了!高分多模卫星首批亚米级立体影像公布
  9. 数据库建模工具(PowerDesigner)
  10. 【Go语言】实现一个简单的纯后端学员管理系统,入门级别练手项目,练习结构体,接口,构造函数