`
风雪涟漪
  • 浏览: 496935 次
  • 性别: Icon_minigender_1
  • 来自: 大连->北京
博客专栏
952ab666-b589-3ca9-8be6-3772bb8d36d4
搜索引擎基础(Search...
浏览量:8767
Ae468720-c1b2-3218-bad0-65e2f3d5477e
SEO策略
浏览量:17675
社区版块
存档分类
最新评论

Schema的优化和索引 - 加速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来创建表的索引。会以排序的方式创建索引,包括了唯一索引。
这个方法对于大表来说,速度格外的快。


分享到:
评论

相关推荐

    SQL语句解释大全-从数据库表中检索数据行和列

    SQL语句解释大全--从数据库表中检索数据行和列 INSERT --向数据库表添加新数据行 DELETE --从数据库表中删除数据行 UPDATE --更新数据库表中的数据 --数据定义 CREATE TABLE --创建一个数据库表 DROP TABLE --...

    SQL语句大全-可当字典用

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 ...

    Transact-SQL语句总结大全

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建...

    SQL 基本命令大全

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 ...

    T-SQL语言指令大全

    T-SQL 的所有指令集结. ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE ...

    汇总:常用 SQl 语句大全。

     ALTER TABLE --修改数据库表结构  CREATE VIEW --创建一个视图  DROP VIEW --从数据库中删除视图  CREATE INDEX --为数据库表创建一个索引  DROP INDEX --从数据库中删除索引  CREATE PROCEDURE --创建一个...

    net实例常用SQL语句大全

     ALTER TABLE --修改数据库表结构  CREATE VIEW --创建一个视图  DROP VIEW --从数据库中删除视图  CREATE INDEX --为数据库表创建一个索引  DROP INDEX --从数据库中删除索引  CREATE PROCEDURE --创建一个...

    SQL语句大全大全(经典珍藏版).

    -从数据库中删除表 ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建...

    常用SQL语句大全

    DROP TABLE --从数据库中删除表 ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 ...

    SQL语句大全大全(经典珍藏版)

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 ...

    SQL语句大全大全(官方修正典藏版)

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 ...

    SQL语句大全

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 ...

    SQL语句全集及操作大全

    ALTER TABLE --修改数据库表结构 CREATE VIEW --创建一个视图 DROP VIEW --从数据库中删除视图 CREATE INDEX --为数据库表创建一个索引 DROP INDEX --从数据库中删除索引 CREATE PROCEDURE --创建一个存储过程 DROP ...

    学习SQL语句之SQL语句大全

     ALTER TABLE --修改数据库表结构  CREATE VIEW --创建一个视图  DROP VIEW --从数据库中删除视图  CREATE INDEX --为数据库表创建一个索引  DROP INDEX --从数据库中删除索引  CREATE PROCEDURE --创建一个...

    orcale常用命令

    ALTER TABLE 表名 ADD (列说明列表) 例:为test表增加一列Age,用来存放年龄 sql>alter table test add (Age number(3)); 修改基表列定义命令如下: ALTER TABLE 表名 MODIFY (列名 数据类型) 例:将test...

    mysql数据库的基本操作语法

    索引是存放在模式(schema)中的一个数据库对象,索引的作用就是提高对表的检索查询速度, 索引是通过快速访问的方法来进行快速定位数据,从而减少了对磁盘的读写操作。 索引是数据库的一个对象,它不能独立存在,...

    高性能MySQL(第3版).part2

    4.5加快ALTERTABLE操作的速度136 4.5.1只修改.frm文件137 4.5.2快速创建MyISAM索引139 4.6总结140 第5章创建高性能的索引141 5.1索引基础141 5.1.1索引的类型142 5.2索引的优点152 5.3高性能的索引策略153 ...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    日期类型 date 7字节 用于存储表中的日期和时间数据,取值范围是公元前4712年1月1日至公元9999年12月31日,7个字节分别表示世纪、年、月、日、时、分和秒 二进制数据类型 row 1~2000字节 可变长二进制数据,在具体...

Global site tag (gtag.js) - Google Analytics