在MySQL数据库中,没有类似于SQL Server数据库或Oracle数据库中索引重建的语法(ALTER INDEX ... REBUILD),那么在MySQL数据库中,是否有什么方式重建索引呢? 在官方文档中"2.11.10Rebuilding or Repairing Tables or Indexes"中,提到下面三种方式可以Rebuild Index

·Dump and Reload Method

·ALTER TABLE Method

·REPAIR TABLE Method

另外, OPTIMIZE TABLE也会对索引进行重建,下面我们来简单验证、测试一下,如有不对或不足的地方,敬请指正。

第一种方法(mysqldump导出然后重新导入),相当于重新CREATE INDEXES , 这里就不讨论了。下面我们来看看其它几种方法,那么要判断索引是否REBUILD了呢?我们来测试验证一下吧,新建测试表如下:

CREATE TABLE t1 (c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,c2 VARCHAR(100),c3 VARCHAR(100) )ENGINE=InnoDB;create index ix_t1_c2 on t1(c2);

DROP INDEX + CREATE INDEX方法

这种方法过于简单,这里不叙说了。其实也没有啥好说的。

ALTER TABLE方法

那么我们能否在MySQL中找到索引的创建或修改时间呢?经过查证,目前而言,MySQL中是没有相关系统表或视图会记录索引的创建时间的,我们可以用间接的方法来间接验证,有些方法不是特别可靠和准确,最准确的方法应该是阅读源码:

1:表的创建时间,可以间接推断索引的创建时间。因为索引的创建时间肯定在表的创建时间之后。

2:对应表的idb文件的修改或创建时间(若文件从创建后不曾修改过则可认为创建时间=修改时间,关于更多详细内容,参考”),当然这种方法不是非常准确。我们知道,对于InnoDB存储引擎的表而言,对应的索引数据存储在ibd文件中,所以文件的创建时间或修改时间是间接判断索引创建时间。如果存储引擎为MyISAM的话,还有专门的索引文件MYI。

注意:show indexes from tablename不会显示索引创建时间

mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name='t1';+------------+---------------------+| TABLE_NAME | CREATE_TIME         |+------------+---------------------+| t1         | 2019-10-20 08:18:33 |+------------+---------------------+1 row in set (0.01 sec)

然后我们对表进行ALTER TABLE t1 ENGINE = InnoDB;进行操作后,然后去验证表的创建时间,如下所示,其实ALTER TABLE xxx ENGINE=InnoDB 其实等价于REBUILD表(REBUILD表就是重建表的意思),所以索引也等价于重新创建了。

在另外一个窗口,我们对比t1.ibd的创建时间,如下所示,也间接验证了表和索引都REBUILD了。(这里是MySQL 8.0.18 ,如果是之前的版本,还有frm之类的文件。)

[root@db-server MyDB]# ls -lrt t1*-rw-r-----. 1 mysql mysql 131072 Oct 20 08:18 t1.ibd[root@db-server MyDB]# stat t1.ibdFile: ‘t1.ibd’Size: 131072          Blocks: 224        IO Block: 4096   regular fileDevice: fd00h/64768d    Inode: 106665154   Links: 1Access: (0640/-rw-r-----)  Uid: ( 1000/   mysql)   Gid: ( 1000/   mysql)Context: system_u:object_r:mysqld_db_t:s0Access: 2019-10-20 08:18:25.911990445 +0800Modify: 2019-10-20 08:18:33.626989940 +0800Change: 2019-10-20 08:18:33.626989940 +0800Birth: -[root@db-server MyDB]# stat t1.ibdFile: ‘t1.ibd’Size: 131072          Blocks: 224        IO Block: 4096   regular fileDevice: fd00h/64768d    Inode: 106665156   Links: 1Access: (0640/-rw-r-----)  Uid: ( 1000/   mysql)   Gid: ( 1000/   mysql)Context: system_u:object_r:mysqld_db_t:s0Access: 2019-10-20 08:20:50.866980953 +0800Modify: 2019-10-20 08:20:51.744980896 +0800Change: 2019-10-20 08:20:51.744980896 +0800Birth: -

REPAIR TABLE方法

REPAIR TABLE方法用于修复被破坏的表,而且它仅仅能用于MyISAM,ARCHIVE,CSV类型的表。下面的测试环境为MySQL 5.6.41,创建测试表,然后对表进行REPAIR TABLE操作

mysql> CREATE TABLE t (->     c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,->     c2 VARCHAR(100),->     c3 VARCHAR(100) )-> ENGINE=MyISAM;Query OK, 0 rows affected (0.01 sec)mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name='t';+------------+---------------------+| table_name | create_time         |+------------+---------------------+| t          | 2019-10-20 08:35:43 |+------------+---------------------+1 row in set (0.00 sec)

然后对表t进行修复操作,发现表的create_time没有变化,如下所示:

mysql> REPAIR TABLE t;+--------+--------+----------+----------+| Table  | Op     | Msg_type | Msg_text |+--------+--------+----------+----------+| MyDB.t | repair | status   | OK       |+--------+--------+----------+----------+1 row in set (0.01 sec)mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name='t';+------------+---------------------+| table_name | create_time         |+------------+---------------------+| t          | 2019-10-20 08:35:43 |+------------+---------------------+1 row in set (0.00 sec)

在另外一个窗口,我们发现索引文件t.MYI的修改时间和状态更改时间都变化了,所以判断索引重建(Index Rebuild)了。

[root@testlnx02 MyDB]# ls -lrt t.*-rw-rw----. 1 mysql mysql 8608 Oct 20 08:35 t.frm-rw-rw----. 1 mysql mysql 1024 Oct 20 08:35 t.MYI-rw-rw----. 1 mysql mysql    0 Oct 20 08:35 t.MYD[root@testlnx02 MyDB]# stat t.MYIFile: `t.MYI'Size: 1024            Blocks: 8          IO Block: 4096   regular fileDevice: fd00h/64768d    Inode: 1836747     Links: 1Access: (0660/-rw-rw----)  Uid: (   27/   mysql)   Gid: (   27/   mysql)Access: 2019-10-20 08:36:02.395428301 +0800Modify: 2019-10-20 08:35:43.112562600 +0800Change: 2019-10-20 08:35:43.112562600 +0800[root@testlnx02 MyDB]# stat t.MYIFile: `t.MYI'Size: 1024            Blocks: 8          IO Block: 4096   regular fileDevice: fd00h/64768d    Inode: 1836747     Links: 1Access: (0660/-rw-rw----)  Uid: (   27/   mysql)   Gid: (   27/   mysql)Access: 2019-10-20 08:37:19.686899429 +0800Modify: 2019-10-20 08:37:10.271475420 +0800Change: 2019-10-20 08:37:10.271475420 +0800

OPTIMIZE TABLE方法

OPTIMIZE TABLE也可以对索引进行重建,官方文档的介绍如下:

OPTIMIZE TABLEreorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table. The exact changes made to each table depend on thestorage engineused by that table.

OPTIMIZE TABLEusesonline DDLfor regular and partitioned InnoDB tables, which reduces downtime for concurrent DML operations. The table rebuild triggered byOPTIMIZE TABLEand performed under the cover byALTER TABLE ... FORCEis completed in place. An exclusive table lock is only taken briefly during the prepare phase and the commit phase of the operation. During the prepare phase, metadata is updated and an intermediate table is created. During the commit phase, table metadata changes are committed.

OPTIMIZE TABLErebuilds the table using the table copy method under the following conditions:

·

·When theold_alter_tablesystem variable is enabled.

·

·When the server is started with the--skip-newoption.

OPTIMIZE TABLEusingonline DDLis not supported for InnoDB tables that contain FULLTEXT indexes. The table copy method is used instead.

简单来说,OPTIMIZE TABLE操作使用Online DDL模式修改Innodb普通表和分区表,

该方式会在prepare阶段和commit阶段持有表级锁:在prepare阶段修改表的元数据并且创建一个中间表,在commit阶段提交元数据的修改。

由于prepare阶段和commit阶段在整个事务中的时间比例非常小,可以认为该OPTIMIZE TABLE的过程中不影响表的其他并发操作。

测试验证如下,对表t1做了OPTIMIZE TABLE后, 表的创建时间变成了2019-10-20 08:41:57

mysql> OPTIMIZE TABLE t1;+---------+----------+----------+-------------------------------------------------------------------+| Table   | Op       | Msg_type | Msg_text                                                          |+---------+----------+----------+-------------------------------------------------------------------+| MyDB.t1 | optimize | note     | Table does not support optimize, doing recreate + analyze instead || MyDB.t1 | optimize | status   | OK                                                                |+---------+----------+----------+-------------------------------------------------------------------+2 rows in set (0.67 sec)mysql> SELECT table_name,create_time FROM  information_schema.TABLES WHERE table_name='t1';+------------+---------------------+| TABLE_NAME | CREATE_TIME         |+------------+---------------------+| t1         | 2019-10-20 08:41:57 |+------------+---------------------+1 row in set (0.00 sec)

另外,网上有种说法ANALYZE TABLE方法也可以重建索引,其实ANALYZE TABLE是不会对索引进行重建的。测试验证的话,你会发现ibd文件没有变化,表的修改时间/状态更改时间也没有变化。

总结:

测试完后,还是感觉MySQL索引重建的方式怪怪的,可能是有先入为主的观念。总结一下MySQL索引重建的方法:

1: DROP INDEX + RECREATE INDEX.

2: ALTER TABLE方法

3: REPAIR TABLE方法,这种方法对于InnoDB存储引擎的表无效。

4: OPTIMIZE TABLE方法

参考资料:

https://dev.mysql.com/doc/refman/8.0/en/rebuilding-tables.html

https://docs.oracle.com/cd/E17952_01/mysql-5.6-en/rebuilding-tables.html

mysql 重置表索引_MySQL如何进行索引重建操作?相关推荐

  1. mysql 重置表索引_MySQL管理表和索引

    MySQL管理表和索引 SQL语句: 数据库 表 索引 视图 DML创建数据库: CREATE DATABASE|SCHEMA [IF NOT EXISTS] db_name [CHARACTER S ...

  2. mysql 回表 覆盖索引_MySQL 的覆盖索引与回表的使用方法

    两大类索引 使用的存储引擎:MySQL5.7 InnoDB 聚簇索引 * 如果表设置了主键,则主键就是聚簇索引 * 如果表没有主键,则会默认第一个NOT NULL,且唯一(UNIQUE)的列作为聚簇索 ...

  3. mysql 回表查询优化_MySQL中的回表查询与索引覆盖:一次百万级别分页查询使用Limit 从90秒到0.6毫秒的优化...

    这里写目录标题 事故现场 解决方案 提到的"回表查询" InnoDB的索引 什么是回表查询 怎么优化回表查询 事故现场 数据库使用的MySQL,有一个日志表,需要进行分页查询,于是 ...

  4. mysql 回表查询优化_MySQL优化:如何避免回表查询?什么是索引覆盖?

    转自:https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651962609&idx=1&sn=46e59691257 ...

  5. mysql 二叉树表设计_Mysql 索引模型 B+ 树详解

    一.认识二叉树 首先,在了解 mysql 中的 B+ 树之前,我们需要搞懂什么是二叉树.二叉树是一种常见的非线形数据结构,数据是以一对多的形态组织起来的,我画了一张图来帮助你理解: 在二叉树中,有一种 ...

  6. mysql 回表查询优化_mysql:若何行使笼罩索引制止回表优化查询

    说到笼罩索引之前,先要领会它的数据结构:B+树. 先建个表演示(为了简朴,id按顺序建): id name 1 aa 3 kl 5 op 8 aa 10 kk 11 kl 14 jk 16 ml 17 ...

  7. mysql 回表 覆盖索引_mysql 14 覆盖索引+回表

    举个栗子,假如有一张表:tableA t(id PK, name KEY, sex, flag);  即id是聚集索引,name是普通索引. 分别执行2条SQL SQL1 :   select id, ...

  8. mysql 唯一索引_MySQL学会用索引,让你数据库的查询速度起飞

    MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度.打个比方,如果合理的设计且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一 ...

  9. mysql 查询优化 非索引_mysql 查询优化和索引使用心得

    -- sql优化案例 -- 1.not in 用left join on 替换 -- 2.like '%XXX%' 用 like 'XXX%' 替换 -- 3.limit 优化 实用,在分页中 EXP ...

最新文章

  1. Java Socket编程 - 基于TCP方式的二进制文件传输【转】http://blog.csdn.net/jia20003/article/details/8248221...
  2. LevelDB (1)概述
  3. Mysql清理binlog日志
  4. Linux + RIL.pdf
  5. SAP CRM和Cloud for Customer的UI界面皮肤更改
  6. java中函数是什么_[一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念...
  7. [物理学与PDEs]第1章习题6 无限长载流直线的磁场
  8. Zoho:尽快修复已遭利用的 ManageEngine 严重漏洞
  9. webgate 重构 工作进度计划
  10. 狂神JAVA笔记--入门篇
  11. sql连表查询、子查询、组合查询
  12. 在MacOS系统下DMG文件显示压缩包无法双击安装解决办法
  13. 【系统分析师之路】第七章 复盘系统设计(业务流程建模)
  14. Web安全测试:使用火狐浏览器修改请求参数
  15. AntDesignVue表格中列的自定义隐藏与展示
  16. 与chatGPT的第一次亲密接触
  17. lms算法的matlab实现,Matlab LMS 算法和 RLS 算法实现
  18. Ubuntu 系列学习(一)Ubuntu常用命令
  19. matplotlib.pyplot plt绘图颜色大全,及plt.plot()的使用
  20. 重磅出击,20张图带你彻底了解ReentrantLock加锁解锁的原理

热门文章

  1. 首个windowsForm应用项目 1123
  2. jquery-尺寸相关
  3. Anti-Tech论 | 技术是如何一步一步腐蚀思想的?
  4. 《Web异步与实时交互——iframe AJAX WebSocket开发实战》—— 1.4 内容安排
  5. Zabbix监控指定端口的步骤
  6. openwabmail问题解决方法
  7. VS2005常用插件
  8. 350个特性看透ES6
  9. Oracle dbms_random随机函数包
  10. Oracle导入TYPE对象报错ORA-02304