MySQL -- Fast Index Creation

2023-05-16

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MySQL -- Fast Index Creation 的相关文章

  • 使用唯一索引删除重复项

    我在两个表字段 A B C D 之间插入 相信我已经在 A B C D 上创建了唯一索引以防止重复 然而我以某种方式简单地对这些做了一个正常的索引 因此插入了重复项 这是2000万条记录的表 如果我将现有索引从普通索引更改为唯一索引 或者只
  • 通过货币换算获取每种产品类型的最低价格

    我想选择每种产品类型中最便宜的 包括运费 价格转换为当地货币 最便宜 产品 价格 产品 运费 seller to aud 我的数据库有如下表 PRODUCTS SELLERS id type id seller id price shipp
  • 将 UPDATE 转换为 INSERT INTO ON DUPLICATE KEY UPDATE 语句

    我有这个 UPDATE MySQL 语句 效果很好 UPDATE table1 Inner Join table2 ON table2 id table1 gw id SET table1 field1 1 table1 field2 2
  • mySQL MATCH 跨多个表

    我有一组 4 个表 我想对其进行搜索 每个都有全文索引 查询可以使用每个索引吗 CREATE TABLE categories id int 5 unsigned NOT NULL auto increment display order
  • 无法启动 MySQL 服务器 - 控制进程退出并出现错误代码

    我的 mysql 服务器停止后无法启动 命令使用 sudo etc init d mysql restart Error 重新启动 mysql 通过 systemctl mysql serviceJob for mysql service
  • 如何使用 MySQL 的 LOAD DATA LOCAL INFILE 在导入 CSV 时将字符串日期更改为 MySQL 日期格式

    我正在使用 MySQL 的 LOAD DATA LOCAL INFILE SQL 语句将数据从 CSV 文件加载到现有数据库表中 下面是一个 SQL 语句示例 LOAD DATA LOCAL INFILE file csv INTO TAB
  • 如何在 Laravel 查询中使用多个 OR,AND 条件

    我需要 Laravel 查询帮助 我的自定义查询 返回正确结果 Select FROM events WHERE status 0 AND type public or type private 如何写这个查询Laravel Event w
  • 截断 Mysql 表 Cron 作业?

    我在如何使用 cron 作业截断 Mysql 表时遇到了一些麻烦 无论我尝试什么 我似乎都无法让数据库清除表格 感谢您的帮助 mysql uderp example pexample hlocalhost Dexample e TRUNCA
  • 为什么这会返回资源 id #2? [复制]

    这个问题在这里已经有答案了 可能的重复 我如何从 PHP 中的 MySql 响应中 回显 资源 id 6 https stackoverflow com questions 4290108 how do i echo a resource
  • MYSQL 区分大小写的 utf8 搜索(使用 hibernate)

    我的登录表具有 utf8 字符集和 utf8 排序规则 当我想要检查用户名并检索该特定用户名的其他信息时 hql 查询会为我提供小写和大写相同的结果 我应该如何处理适用于案例的 HQL 查询 我使用 Mysql 5 和 java hiber
  • InnoDB 因读未提交而死锁! - Java - Glassfish - EJB3(JPA/Hibernate)

    几天来 我在使用 Glassfish EJB3 和 Mysql InnoDB 的 Java 应用程序上遇到了死锁问题 配置 Mysql InnoDB Ver 14 12 Distrib 5 0 51a 适用于 debian linux gn
  • 为什么我的 if 语句没有按我预期的方式工作?

    我正在尝试实现以下目标 我向我的 SQL 数据库询问使用SELECT FROM subjects 这样做之后我要求使用数组mysqli fetch assoc 在那之前一切都很好 现在的问题是 当我尝试在每个循环中修改 genero 的值
  • 使用 PHP 的 MySQL 连接字符串

    我正在尝试通过本地计算机连接到托管在我的服务器上的数据库 我的服务器有cPanel 11 它是一个典型的共享服务器 由CentOS提供支持 安装了PHP和MySQL 准确地说 我在同一台服务器上持有经销商帐户 我想在不同帐户或域之间访问数据
  • MySQL PHP邮政编码比较具体距离

    我试图找出比较一个邮政编码 用户提供的 和一大堆其他邮政编码 现在大约有 200 个邮政编码 之间的距离的最有效方法 相对于加载时间 但它会随着时间的推移而增加 我不需要任何精确的东西 只是在球场上 我下载了整个美国的邮政编码 csv 文件
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • MySQL MIN/MAX 所有行

    我有桌子Races与行ID Name and TotalCP 我选择分钟 TotalCP FROM Races 但是我想选择具有最小值的整行 我如何在单个查询中做到这一点 从聚合值获取整行的一般形式是 SELECT FROM Races W
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样
  • MySQL连接字符集问题

    我在 Mac 上使用带有 MySQL 的 velosurf 没有任何编码问题 但是当我切换到 Linux 计算机时 从 velosurf 获得的值未正确编码 我发现这可能是默认连接字符集的问题 在 Mac 上我得到 mysql gt sho
  • 比特纳米。重置mysql根密码

    我如何重置 MySQL 中的 root 密码和帐户 因为我按照如何为其他服务器授予权限的说明操作 并且意外地将 root 用户 Mysql 绑定到其他 IP 地址 现在看来我无法在 localhost 上以管理员身份登录 Thanks 您有
  • 在 MySQL 中存储表情符号的编码问题:如何使用 Prisma ORM 在 NodeJS 中定义字符排序规则?

    亲爱的 Nodejs 专家和数据库专家 我们在 MySQL 数据库中存储表情符号和其他特殊字符时遇到问题 我们使用 Prisma 得到一个错误 这是我们使用的 ORM 参数无法从排序规则 utf8 general ci 转换为 utf8mb

随机推荐

  • 安装完office2016 64位后,在安装visio时,报错,无法安装,

    安装环境要求 xff1a 系统要求 xff1a win8 win10等 xff1b office要求 xff1a sw 批量版 不能和cn xff08 零售版 xff09 365版混装 重点注意事项一定要注意批量版和零售版的区别 xff0c
  • tex中把参考文献标题删除

    如果是book类 lt br gt renewcommand bibname lt br gt 如果是article类 lt br gt renewcommand refname
  • 德州扑克AI--Programming Poker AI(译)

    前言 最近在研究德州扑克的AI 也想由浅入深的看下 在网上找了一圈 发现很多文章都提到了一篇文章 Programming Poker AI 仔细拜读了一下 觉得非常不错 这里作下简单的翻译工作 可能加些自己的一些理解 权当做一回大自然的搬运
  • centos7优化内核参数详解

    一 Sysctl命令用来配置与显示在 proc sys目录中的内核参数 xff0e 如果想使参数长期保存 xff0c 可以通过编辑 etc sysctl conf文件来实现 命令格式 xff1a sysctl n e w variable
  • 50行代码实现3D模拟真实撒金币动效

    我们将会用50行不到的代码来实现一个3D模拟撒金币动效 你只需要一点Egret基础就能够快速上手 xff0c 如果你不了解Egret xff0c 这里有一篇3分钟创建hello world来带你快速入门 实现效果 源码和在线demo 完整的
  • 微信小程序之——自定义分享按钮(完整版)

    声明 onShareAppMessage 函数 onShareAppMessage return title 39 弹出分享时显示的分享标题 39 desc 39 分享页面的内容 39 path 39 page user id 61 123
  • SQL Server developer和enterprise有什么区别?以及各个版本的定义

    1 Enterprise 作为高级版本 xff0c SQL Server Enterprise 版提供了全面的高端数据中心功能 xff0c 性能极为快捷 虚拟化不受限制 xff0c 还具有端到端的商业智能 xff0c 可为关键任务工作负荷提
  • java 图形界面---字体的设置

    Java绘图中 xff0c 显示文字的方法主要有三种 xff1a xff08 1 xff09 drawString String str int x int y xff1a 在指定的位置显示字符串 xff08 2 xff09 drawCha
  • "不能为虚拟电脑 ubuntu 打开一个新任务"的解决办法

    使用virtualbox报错 xff1a 不能为虚拟电脑 ubuntu3 打开一个新任务 The virtual machine 39 ubuntu3 39 has terminated unexpectedly during startu
  • 获取当前程序所在路径/目录

    char path buffer MAX PATH char drive MAX DRIVE char dir MAX DIR char fname MAX FNAME char ext MAX EXT GetModuleFileName
  • 理解Windows内核模式与用户模式

    内核层次架构 windows程序运行分为内核模式和用户模式 xff0c 内核模式可以访问所有的内存地址空间 xff0c 并且可以访问所有的CPU指令 一般程序运行在用户模式 xff0c 通过系统调用切换到内核模式执行系统功能 xff0c W
  • 自定义加数字

    每一位同时加 lt html gt lt head gt lt meta name 61 34 generator 34 content 61 34 HTML Tidy for HTML5 experimental for Windows
  • 使用C++ REST SDK开发简单的Web(HTTP)服务

    C 43 43 REST SDK是微软开源的一套客户端 服务器通信库 xff0c 提供了URI构造 解析 xff0c JSON编解码 xff0c HTTP客户端 HTTP服务端 xff0c WebSocket客户端 xff0c 流式传输 x
  • 头文件 INTRINS.H 的用法

    KEIL中头文件INTRINS H的作用 在C51单片机编程中 xff0c 头文件INTRINS H的函数使用起来 xff0c 就会让你像在用汇编时一样简便 内部函数 描述 crol 字符循环左移 cror 字符循环右移 irol 整数循环
  • 数模转换模块PCF8591

    介绍 有些传感器的输出值有模拟值 xff0c 这样的数值是不可读的 xff0c 如果想要把这些模拟值变为可读的 xff0c 就必须要用到数模转化模块 PCF8591是一个单片集成 单独供电 低功耗 8 bit CMOS数据获取器件 PCF8
  • 香橙派Orangepi Zero2控制舵机转动

    通过香橙派输出PWM波控制舵机 xff0c 首先需要了解Linux的定时器功能 xff0c 通过配置定时器产生PWM波 xff1a 218条消息 Linux时间函数与定时器简介 xff2c xff2a xff38 的博客 CSDN博客 1
  • UDP Linux编程(客户端&服务器端)

    服务器端 服务器不用绑定地址 xff0c 他只需要进行绑定相应的监听端口即可 include lt sys types h gt include lt sys socket h gt include lt pthread h gt incl
  • Visual Studio 与 Visual C++ 关系

    Visual Studio netVisual C 43 43 netVisual C 43 43 MSC VER备注Visual Studio net 2002Visual C 43 43 net 2002Visual C 43 43 7
  • C语言之基本算法08—去掉最高分去掉最低分求平均值

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • MySQL -- Fast Index Creation

    1 fast index creation简介 MySQL5 5之后 xff0c 对innodb表创建或删除辅助索引的效率提升了很多 xff0c 即增加了新的功能fast index creation 因为MySQL5 5之后 xff0c