MySQL -- Fast Index Creation
1.fast index creation简介
MySQL5.5之后,对innodb表创建或删除辅助索引的效率提升了很多,即增加了新的功能fast index creation。因为MySQL5.5之后,创建和删除辅助索引不在需要拷贝整个表的数据。
在5.5之前,在一个已经存在数据的表上增加或者删除索引是很耗时的。create index或drop index按照以下的方式进行工作:
-创建一个新的、空的临时表,表结构为使用alter table定义的新结构
-逐一拷贝数据到新表,插入数据行同时更新索引
-删除原表
-将新表的名字改为原表的名字
快速索引创建只是对辅助索引有效,对主键索引无效。innodb的表存储时是基于主键的聚集索引来组织的,在oracle中这种方式叫做“索引组织表”。因为表结构仅仅依赖于主键,所以重定义主键仍然要按照5.5之前的方式进行数据拷贝。
fast index creation机制也可以加快对索引组织表的load操作的效率。先创建只有聚集索引的表,数据load结束后,再创建辅助索引。
2.fast index creation的扩展
可以通过一条alter table语句在表上定义多个辅助索引。这样的效率会很高,因为聚集索引只需要被扫描一次。例如:
create table t1(a int primary key, b int, c char(1)) engine=innodb;
insert into t1 values(1,2,'a'),(2,3,'b'),(3,2,'c'),(4,3,'d'),(5,2,'e');
commit;
alter table t1 add index(b),add unique index(c);
如果在alter table之前,表中已经有大量的数据,这样会比先创建好所有的辅助索引后在加载数据的效率高。
也可分开创建辅助索引,但是分开创建每次都要执行一次聚集索引的扫描。效率会低。如:
create index b on t1 (b);
create unique index c on t1 (c);
删除辅助索引不需要拷贝数据。
innodb中重构聚集索引,无论是5.5之前还是之后,都需要拷贝表中的数据。如果用户创建表的时候,没有创建主键,innodb会自动提用户选择一个,通常是第一个唯一性非空索引或系统自动产生的键。
后期定义一个主键需要拷贝数据:
create table t2 (a int, b int) engine=innodb;
insert into t2 values (null, 1);
alter table t2 add primary key (b);
当创建一个唯一性或主键索引时,innodb需要做一些额外的工作。对于唯一性索引,innodb需要检查表是否包含重复的值;对于主键索引innodb除了检查是否有重复的值,还要检查是否有空值。
建议在创建表的时候就定义好主键,这样可以避免后期对表进行rebuild操作。
3.fast index creation的实现原理
innodb有两种类型的索引:聚集索引、辅助索引。
聚集索引包含Btree节点中数据,增加、删除聚集索引都要涉及拷贝数据、创建表新的拷贝;辅助索引只是包含索引键和主键的值,删除或新建都不要拷贝聚集索引中的数据。
当修改主键的时候,所有辅助索引都要被重新创建。
删除辅助索引比较简单。只会更新innodb内部系统表和mysql数据字典,来表明该索引已经不存在。innodb会归还该索引占用的存储空间。
增加辅助索引,innodb会扫描表,借助内存和临时文件排序辅助索引涉及的列,创建btree索引。
4.fast index creation对并发的考虑
在innodb创建、删除辅助索引的时候,表会被加上共享锁。任何写都会被阻止,但是可以读。
当修改聚集索引的时候,表会被排它锁锁住,因为要拷贝数据,在创建新的聚集索引的时候,所有操作都会被阻止。
create index、alter table都会等待表上的当前事务结束。alter table重新定义主键还会等待表上所有的select语句结束。在聚集索引重期间,任何请求都不支持,因为表要被删除和重建。
create index、alter table创建辅助索引的时候,对表的读操作可以执行,但是不能更新数据。
新创建的附注索引只是包含create index、alter table命令开始执行时候的数据。不包含任何未提交的值、老版本的值、以及被标记为删除但是尚未移除的值。
5.crash recovery和fast index creation如何工作
在mysql server 发生crash的时候,执行alter table 不会有数据丢失。但是,对聚集索引和辅助索引的crash recovery过程还是有区别的。
如果在创建辅助索引的时候发生了crash,recovery时,mysql会删除已经创建的部分索引。必须重新执行alter table、create index命令。
如果在创建聚集索引的时候发生了crash,recovery过程就比较复杂了,因为数据必须要全备拷贝到新建的聚集索引。innodb的表都是按照聚集索引存储的。
mysql创建新的聚集索引,通过将原表中的数据拷贝到一个临时表。一旦数据拷贝结束,原表就会被重命名成一个零时表,而新建的临时表会被改成原表的名字,接着删除原表。
如果在创建聚集索引的时候发生了crash,没有数据会被丢失,但是必须使用新建的临时表完成recovery。重建聚集索引和重定义主键都是很少发生,所以官方文档没有详细涉及如何recovery的过程,可能需要联系mysql service。
6.fast index creation的限制
在创建、删除过程要考虑下面因素:
-创建索引时,文件会被写到临时目录($tmpdir)。要确保临时目录空间足够大
-如果一条alter table对同一个表进行drop index,add index,无法使用fast index creation
-在临时表上创建索引,只能用数据拷贝,而不能用fast index creation
-为了避免innodb数据字典和mysql数据字典冲突,使用alter table ... change重命名列名的时候用表拷贝而不是fast index creation
-optimize table不支持fast index creation
MySQL -- Fast Index Creation的更多相关文章
- MySQL Index--CREATE INDEX在各版本的优化
FIC(Fast index creation)特性在MySQL 5.5版本中引入FIC(Fast index creation)特性,创建索引时无需再拷贝整表数据,以提升索引的创建速度. FCI 操 ...
- mysql force index() 强制索引的使用
mysql force index() 强制索引的使用 之前跑了一个SQL,由于其中一个表的数据量比较大,而在条件中有破坏索引或使用了很多其他索引,就会使得sql跑的非常慢... 那我们怎么解决呢? ...
- MySQL force Index 强制索引概述
以下的文章主要介绍的是MySQL force Index 强制索引,以及其他的强制操作,其优先操作的具体操作步骤如下:我们以MySQL中常用的hint来进行详细的解析,如果你是经常使用Oracle的 ...
- MySQL报错: Character set ‘utf8mb4‘ is not a compiled character set and is not specified in the ‘/usr/share/mysql/charsets/Index.xml‘ file
由于日常程序使用了字符集utf8mb4,为了避免每次更新时,set names utf8mb4,就把配置文件改了,如下: [root@~]# vim /etc/my.cnf #my.cnf [clie ...
- mysql use index() 优化查询
mysql use index() 优化查询 FORCE INDEX/IGNORE INDEX 的语法: SELECT *** FROM TABLE [{USE|IGNORE|FORCE} INDEX ...
- mysql: Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/share/mysql/charsets/Index.xml' file
mysql: Character set 'utf8mb4' is not a compiled character set and is not specified in the '/usr/sha ...
- Mysql force index和ignore index 使用实例
前几天统计一个sql,是一个人提交了多少工单,顺便做了相关sql优化.数据大概2000多w. select CustName,count(1) c from WorkOrder where Creat ...
- [MySQL]show index from tb_name命令各列的含义
show index from table_name 这个命令有助于诊断性能低下的查询,尤其是查询是否使用了可用的索引. 下面介绍下 这个命令显示的结果列的含义: | Table | Non_uniq ...
- MySQL 索引 INDEX
索引用于快速找出在某列中有特定值的行. 不使用索引,MySQL必须从第一条记录开始读完整个表,直到找到相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一 ...
随机推荐
- centos7默认安装没有连接到网络
1.显示所有连接 # nmcli con show 2.连接到网络 # nmcli con up enp0s3 这个ens33是通过显示所有连接查到的
- C#正则表达式 - 精通版
1.正则所需要的命名空间是 using System.Text.RegularExpressions 2.创建Regex对象 new Regex(string pattern,RegexOptions ...
- [网摘][医学影像] DICOM 和 NIFTI 基础知识与区别
查找DICOM基础知识时,看到这篇文章里面写了一些关于使用深度学习进行医疗影像分析:文件格式篇.下文摘自:https://www.jiqizhixin.com/articles/2017-07-31 ...
- Selenium2(WebDriver)总结(二)---Firefox的firebug插件参数设置(补充)
本文是对上一节的补充:http://www.cnblogs.com/puresoul/p/4251536.html 使用Selenium2(webdriver)启动firefox且自动加载firebu ...
- 微信小程序 - 非入侵式布局
非入侵式布局,就是不影响原有内容以及代码,增加用户体验感(UE)的一种方式. 例如我们每个接口必须返回: 0:请求成功 -1:请求失败 .... 这样就便于前端判断数据是否加载成功,然后以客观的方式提 ...
- web.xml关于spring的讲解
<context-param>的作用: web.xml的配置中<context-param>配置作用 . 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件w ...
- Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node ……
解决办法是加一个等待时间即可解决问题: setTimeout(function () { you code }, );
- 阿里历年经典Java面试题汇总,想进BAT你还不快收藏!
转载:https://mp.weixin.qq.com/s/M8YyxloxZnMACH9QCQN7HA Volatile的特征: A.禁止指令重排(有例外) B.可见性 Volatile的内存语义: ...
- java HMAC_SHA1加密算法
java HMAC_SHA1加密算法 CreationTime--2018年7月14日16点46分 Author:Marydon 1.准备工作 import javax.crypto.Mac; i ...
- cpan安装报错Invalid host name on line 1 at *FirstTime.pm line 1857.
今天鼓捣一下CPAN,安装时出错: root@ubuntu:~# cpan install DBI CPAN.pm requires configuration, but most of it can ...