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的更多相关文章

  1. MySQL Index--CREATE INDEX在各版本的优化

    FIC(Fast index creation)特性在MySQL 5.5版本中引入FIC(Fast index creation)特性,创建索引时无需再拷贝整表数据,以提升索引的创建速度. FCI 操 ...

  2. mysql force index() 强制索引的使用

    mysql force index() 强制索引的使用 之前跑了一个SQL,由于其中一个表的数据量比较大,而在条件中有破坏索引或使用了很多其他索引,就会使得sql跑的非常慢... 那我们怎么解决呢? ...

  3. MySQL force Index 强制索引概述

    以下的文章主要介绍的是MySQL force Index  强制索引,以及其他的强制操作,其优先操作的具体操作步骤如下:我们以MySQL中常用的hint来进行详细的解析,如果你是经常使用Oracle的 ...

  4. 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 ...

  5. mysql use index() 优化查询

    mysql use index() 优化查询 FORCE INDEX/IGNORE INDEX 的语法: SELECT *** FROM TABLE [{USE|IGNORE|FORCE} INDEX ...

  6. 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 ...

  7. Mysql force index和ignore index 使用实例

    前几天统计一个sql,是一个人提交了多少工单,顺便做了相关sql优化.数据大概2000多w. select CustName,count(1) c from WorkOrder where Creat ...

  8. [MySQL]show index from tb_name命令各列的含义

    show index from table_name 这个命令有助于诊断性能低下的查询,尤其是查询是否使用了可用的索引. 下面介绍下 这个命令显示的结果列的含义: | Table | Non_uniq ...

  9. MySQL 索引 INDEX

    索引用于快速找出在某列中有特定值的行. 不使用索引,MySQL必须从第一条记录开始读完整个表,直到找到相关的行,表越大,查询数据所花费的时间就越多,如果表中查询的列有一个索引,MySQL能够快速到达一 ...

随机推荐

  1. 阿里云centos 6安装iRedmail过程

    全新系统 yum update cd /root wget http://www.iredmail.com/iRedMail-0.8.7.tar.bz2 tar xvf iRedMail-0.8.7. ...

  2. android studio开发的时候出现design editor is unavailable until after a successful project sync问题的解决方法

    android studio设计界面的时候,出现了报错:design editor is unavailable until after a successful project sync,导致无法编 ...

  3. LintCode:Fibonacci

    C++ class Solution{ public: /** * @param n: an integer * @return an integer f(n) */ int fibonacci(in ...

  4. 透彻理解Ioc

    引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...

  5. 【Bugly安卓开发干货】Android APP 高速 Pad 化实现

    Bugly 技术干货系列内容主要涉及移动开发方向.是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创.转载请标明出处. 怎样能在最快的时间内,实现一个最新 ...

  6. linux find command information more

    查找文件find ./ -type f 查找目录find ./ -type d 查找名字为test的文件或目录find ./ -name test 查找名字符合正则表达式的文件,注意前面的‘.*’(查 ...

  7. ROS知识(15)----Actionlib的使用(一)

    Actionlib是ROS非常重要的库,像执行各种运动的动作,例如控制手臂去抓取一个杯子,这个过程可能复杂而漫长,执行过程中还可能强制中断或反馈信息,这时Actionlib就能大展伸手了. 1.原理 ...

  8. java 怎么打印变量

    //Test.java public class Test16{ public static void main(String args[]){ int age=28; System.out.prin ...

  9. Fix: Windows Script Host access is disabled on this machine

    If you receive this Windows Script Host access is disabled on this machine, Contact your administrat ...

  10. 播布客视频PIT专用播放器MBOO2015

    播布客视频,还是挺不错... 很多视频都是pit后缀的,需要用MBOO2015才可以打开... 00.MB2015软件 01.视频样例 02.download 链接: https://pan.baid ...