mysql alter table 速度慢_MySQL中ALTER TABLE时的性能问题
当对于一个大表进行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时的性能问题相关推荐
- mysql explain key为空_MySQL中explain的使用以及性能分析
原标题:MySQL中explain的使用以及性能分析 MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性 ...
- mysql复合主键优缺点_MySQL中的复合主键性能缺陷
INSERT 和 UPDATE 性能变化很小: (INT) 和 (INT, INT) 键几乎相同 . SELECT 复合 PRIMARY KEY 的性能取决于很多因素 . 如果您的表是 InnoDB ...
- mysql锁表_MySQL中Alter table 你不知道的性能问题
前言: MySQL 的大表运维总是令人头疼的一件事,特别是大表表结构的修改尤为困难. 首先,alter table 的process不可被kill , 一旦执行就不可回退. 其次,大多数的alter ...
- mysql 锁24小时_MySQL中Alter table 不长时间锁表的情况汇总。
查看原文:http://www.tanbo.name/html/99669.html 前言: MySQL 的大表运维总是令人头疼的一件事,特别是大表表结构的修改尤为困难. 首先,alter table ...
- mysql改存储引擎教程_MySQL中修改数据表存储引擎的三种方法
第一种方法:ALTER TABLE 将表从一个引擎修改为另一个引擎最简单的办法是使用ALTER TABLE语句,转换表的存储引擎会导致失去原引擎相关的所有特性. 例:将mytable的引擎修改为Inn ...
- mysql 语句怎样修饰约束_MySQL中的约束,添加约束,删除约束,以及一些其他修饰讲解...
(1)创建数据库 CREATE DATABASES 数据库名; (2)选择数据库 USE 数据库名; (3)删除数据库 DROP DATAVBASE 数据库名; (4)创建表 CREATE TABLE ...
- mysql的explain怎么看_mysql中explain用法详解
如果在select语句前放上关键词explain,mysql将解释它如何处理select,提供有关表如何联接和联接的次序. explain的每个输出行提供一个表的相关信息,并且每个行包括下面的列: 1 ...
- mysql约束添加删除数据_mysql中约束的添加,修改,与删除
MySQL中的约束,添加约束,删除约束,以及其他的一些修饰: 一.NOT NULL(非空约束) 添加非空约束 1)建表时直接添加 CREATE TABLE t_user(user_id INT(10) ...
- Mysql修改字段名和长度_mysql中修改表字段名/字段长度/字段类型详解
先来看看常用的方法 MySql的简单语法,常用,却不容易记住.当然,这些Sql语法在各数据库中基本通用.下面列出: 1.增加一个字段: alter table user add COLUMN new1 ...
最新文章
- htmlvideoelement js操作
- 让你的apache支持Perl
- 线段树-Mex-洛谷P4137
- [置顶]别羡慕别人的舒服,静下心来坚持奋斗!!!
- 华为云龙api自动化工具_聊聊华为GDE刚发布的一体化低门槛开发平台ADC 2.0
- 多个 Linux 发行版考虑移除 Chromium 软件包
- 图像压缩算法动态规划c语言,动态规划算法实现数字图像压缩的研究.pdf
- android怎么备份镜像文件,如何备份手机系统镜像? - Android系统区 - 无忧启动论坛 - Powered by Discuz!...
- 数字共享平台赋能船舶行业数字化转型——CSBC,搭建行业数字生态链
- PostgreSQL数据库——Pigsty
- 异常与调试之SEH、UEH、VEH、VCH以及SEH的区别总结——简单好理解
- 二阶魔方入门玩法教程
- JZOJ 6297. 2019.08.10【NOIP提高组A】世界第一的猛汉王
- Glib基础——版本信息
- css3如何实现字体放大缩小动画
- 新的网络架构按下“快进键” 快步走入互联网下半场
- K8S中的pod、services、容器的概念和区别
- sqlserver审计 —— 服务器与数据库审核规范
- 卡尔曼滤波的使用举例
- 大国重器“兵器谱”,了解一下
热门文章
- 解决安装Adobe Acrobat 8.0提示验证原版序列号的问题
- error C2226: 语法错误 : 意外的“HFONT”类型
- ABAP 交货单屏幕增强
- Python调用EasyDLBML模型API实现缺陷检测
- 使用Crypto++5.5.2完成RSA加解密,真正的把公钥放在字符串内,而不是放在文件内
- 使用TripMode 解决MAC nsurlsessiond 狂走流量问题
- 360分身大师 v2.6.9
- SpringSecurity前后端分离下对登录认证的管理
- 手把手教你写一个抢讲座的脚本
- 如何找到那些网红赚钱的密码?