当对于一个大表进行ALTER TABLE的时候,性能问题就产生了。MySQL大部分改动的步骤如下:根据新的表结构创建一个空表,从旧表中把数据取出来插入到新表中,在删除旧表。这是个非常漫长的过程。许多人ALTER TABLE之后,都有等待1小时或者1天的痛苦经历。

MySQL AB已经开始提升这方面的性能了。一些即将到来的特性是支持"在线"的操作,而不会去锁定表。InnoDB的开发者也在积极努力开发以排序来创建索引。MyISAM已经支持这一特性了,结果就是索引更快并且压缩了索引布局。

并不是所有的ALTER TABLE都会使表重建。举个例子,你可以用两个方法更改或者删除列默认值(一个快,一个慢)。如果你想更改一个film的租赁期限为原来的3天到现在的5天。方法如下:

mysql> ALTER TABLE sakila.film

-> MODIFY COLUMN rental_duration TINYINT(3) NOT NULL DEFAULT 5;

用SHOW  STATUS来监控这个语句,它做了1000次读和1000次插入。换句话说就是复制一个表到新表中。即使这个列的类型,大小,是否为NULL都没有改变。

原理上来说,MySQL可以跳过创建新表。这个默认的值实际存储在.frm文件中。因此你可以更改它而没有必要接触表。MySQL也不会做优化,然而任何的MODIFY COLUMN都会导致表的重建。

你可以使用ALTER COLUMN来修改:

mysql> ALTER TABLE sakila.film

-> ALTER COLUMN rental_duration SET DEFAULT 5;

这个语句修改了.frm文件而没有去操作表。结果就是速度非常之快。

仅仅修改.frm文件

我们发现修改标的.frm文件速度非常快并且当它不能那么做的时候,MySQL有的时候会重建表。如果你愿意承担一部分风险,你可以告诉MySQL做一些类型的修改而不去重建表。

你可以不用重建表来做如下类型的操作:

移除列的AUTO_INCREMENT属性。

添加,移除,更改ENUM和SET。如果你移除了一个常量并且一些行包含这个值,查询语句返回这个值将会是空字符串

基本的技术就是创建一个.frm文件并且拷贝它到以存在表的.frm文件的位置。步骤如下:

创建一个空表,当然表布局必须是准确的。除了一些更改的项。

执行FLUSH TABLES WITH READ LOCK.这一步将关闭使用的所有的表并且防止了这些表被打开。

交换.frm文件。

执行UNLOCK TABLES释放读锁。

为了做例子,我们给skila.film表的rating列添加一个常量。当前的列如下:

mysql> SHOW COLUMNS FROM sakila.film LIKE 'rating';

+--------+------------------------------------+------+-----+---------+-------+

| Field  | Type                               | Null | Key | Default | Extra |

+--------+------------------------------------+------+-----+---------+-------+

| rating | enum('G','PG','PG-13','R','NC-17') | YES  |     | G       |       |

+--------+------------------------------------+------+-----+---------+-------+

我们添加一个PG-14到这列中。

mysql> CREATE TABLE sakila.film_new LIKE sakila.film;

mysql> ALTER TABLE sakila.film_new

-> MODIFY COLUMN rating ENUM('G','PG','PG-13','R','NC-17', 'PG-14')

-> DEFAULT 'G';

mysql> FLUSH TABLES WITH READ LOCK;

注意一下我们实在最后添加这个PG-14的,而不是在中间,那样做的话就会修改现有的值了,R值变为PG-14,NC-17变为R依此类推。

现在连交换.frm文件,操作系统命令如下

root:/var/lib/mysql/sakila# mv film.frm film_tmp.frm

root:/var/lib/mysql/sakila# mv film_new.frm film.frm

root:/var/lib/mysql/sakila# mv film_tmp.frm film_new.frm

在回到MySQL提示符,我们要解锁,再来看看更改的结果。

mysql> UNLOCK TABLES;

mysql> SHOW COLUMNS FROM sakila.film LIKE 'rating'G

*************************** 1. row ***************************

Field: rating

Type: enum('G','PG','PG-13','R','NC-17','PG-14')

最后一步要做的就是删除我们已创建的表。

mysql> DROP TABLE sakila.film_new;

快速的创建MyISAM索引

高效的读取MyISAM表一般的技巧是,关闭键,读取数据,重新启用键。

mysql> ALTER TABLE test.load_data DISABLE KEYS;

-- load the data

mysql> ALTER TABLE test.load_data ENABLE KEYS;

这样可以工作的原因是MyISAM延迟了创建键值直到数据读取之后,重要的是,它可以有序的创建索引。结果就非床快并且无碎片和压缩的索引树。

不过,对于唯一索引这种方法就不行了。因为DISABLE KEYS仅仅应用于非唯一的索引。MyISAM在内存中创建唯一索引并且读取每一行来校验唯一性。一旦索引大小超出了内存大小,读取会极度缓慢。

前一部分所说的ALTER TABLE的技巧,可以加速这个过程,前提是你需要多做一点工作和承担一部分风险。这对于备份来说很有用。比如,当你发现所有的数据是无效的并且不需要做唯一性检查。

你需要做的步骤如下:

创建一个期望的表。但是不要有任何的索引。

读取数据来创建MYD文件。

创建另一个空表,这次要包含索引。这会创建.frm和.MYI文件。

用个读锁来刷新表。

对第二个表的.frm和.MYI进行重命名。因此MySQL会把它们当作第一个表使用。

释放读锁。

使用REPAIR TABLE来创建表的索引。会以排序的方式创建索引,包括了唯一索引。

这个方法对于大表来说,速度格外的快。

mysql alter table 速度慢_MySQL中ALTER TABLE时的性能问题相关推荐

  1. mysql explain key为空_MySQL中explain的使用以及性能分析

    原标题:MySQL中explain的使用以及性能分析 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性 ...

  2. mysql复合主键优缺点_MySQL中的复合主键性能缺陷

    INSERT 和 UPDATE 性能变化很小: (INT) 和 (INT, INT) 键几乎相同 . SELECT 复合 PRIMARY KEY 的性能取决于很多因素 . 如果您的表是 InnoDB ...

  3. mysql锁表_MySQL中Alter table 你不知道的性能问题

    前言: MySQL 的大表运维总是令人头疼的一件事,特别是大表表结构的修改尤为困难. 首先,alter table 的process不可被kill , 一旦执行就不可回退. 其次,大多数的alter ...

  4. mysql 锁24小时_MySQL中Alter table 不长时间锁表的情况汇总。

    查看原文:http://www.tanbo.name/html/99669.html 前言: MySQL 的大表运维总是令人头疼的一件事,特别是大表表结构的修改尤为困难. 首先,alter table ...

  5. mysql改存储引擎教程_MySQL中修改数据表存储引擎的三种方法

    第一种方法:ALTER TABLE 将表从一个引擎修改为另一个引擎最简单的办法是使用ALTER TABLE语句,转换表的存储引擎会导致失去原引擎相关的所有特性. 例:将mytable的引擎修改为Inn ...

  6. mysql 语句怎样修饰约束_MySQL中的约束,添加约束,删除约束,以及一些其他修饰讲解...

    (1)创建数据库 CREATE DATABASES 数据库名; (2)选择数据库 USE 数据库名; (3)删除数据库 DROP DATAVBASE 数据库名; (4)创建表 CREATE TABLE ...

  7. mysql的explain怎么看_mysql中explain用法详解

    如果在select语句前放上关键词explain,mysql将解释它如何处理select,提供有关表如何联接和联接的次序. explain的每个输出行提供一个表的相关信息,并且每个行包括下面的列: 1 ...

  8. mysql约束添加删除数据_mysql中约束的添加,修改,与删除

    MySQL中的约束,添加约束,删除约束,以及其他的一些修饰: 一.NOT NULL(非空约束) 添加非空约束 1)建表时直接添加 CREATE TABLE t_user(user_id INT(10) ...

  9. Mysql修改字段名和长度_mysql中修改表字段名/字段长度/字段类型详解

    先来看看常用的方法 MySql的简单语法,常用,却不容易记住.当然,这些Sql语法在各数据库中基本通用.下面列出: 1.增加一个字段: alter table user add COLUMN new1 ...

最新文章

  1. htmlvideoelement js操作
  2. 让你的apache支持Perl
  3. 线段树-Mex-洛谷P4137
  4. [置顶]别羡慕别人的舒服,静下心来坚持奋斗!!!
  5. 华为云龙api自动化工具_聊聊华为GDE刚发布的一体化低门槛开发平台ADC 2.0
  6. 多个 Linux 发行版考虑移除 Chromium 软件包
  7. 图像压缩算法动态规划c语言,动态规划算法实现数字图像压缩的研究.pdf
  8. android怎么备份镜像文件,如何备份手机系统镜像? - Android系统区 - 无忧启动论坛 - Powered by Discuz!...
  9. 数字共享平台赋能船舶行业数字化转型——CSBC,搭建行业数字生态链
  10. PostgreSQL数据库——Pigsty
  11. 异常与调试之SEH、UEH、VEH、VCH以及SEH的区别总结——简单好理解
  12. 二阶魔方入门玩法教程
  13. JZOJ 6297. 2019.08.10【NOIP提高组A】世界第一的猛汉王
  14. Glib基础——版本信息
  15. css3如何实现字体放大缩小动画
  16. 新的网络架构按下“快进键” 快步走入互联网下半场
  17. K8S中的pod、services、容器的概念和区别
  18. sqlserver审计 —— 服务器与数据库审核规范
  19. 卡尔曼滤波的使用举例
  20. 大国重器“兵器谱”,了解一下

热门文章

  1. 解决安装Adobe Acrobat 8.0提示验证原版序列号的问题
  2. error C2226: 语法错误 : 意外的“HFONT”类型
  3. ABAP 交货单屏幕增强
  4. Python调用EasyDLBML模型API实现缺陷检测
  5. 使用Crypto++5.5.2完成RSA加解密,真正的把公钥放在字符串内,而不是放在文件内
  6. 使用TripMode 解决MAC nsurlsessiond 狂走流量问题
  7. 360分身大师 v2.6.9
  8. SpringSecurity前后端分离下对登录认证的管理
  9. 手把手教你写一个抢讲座的脚本
  10. 如何找到那些网红赚钱的密码?