17-大批量插入数据
当用load命令导入数据的时候,适当的设置可以提高导入的速度。
对于MyISAM存储引擎的表,可以通过以下方式快速地导入大量的数据。
ALTER TABLE tbl_name DISABLE KEYS;
loading the data
ALTER TABLE tbl_name ENABLE KEYS;
DISABLE KEYS和ENABLE KEYS用来打开或者关闭MyISAM表非唯一索引的更新。在导入大量的数据到一个非空的 MyISAM 表时,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的 MyISAM 表,默认就是先导入数据然后才创建索引的,所以不用进行设置。
下面的例子中,用LOAD语句导入数据耗时115.12秒:
mysql> load data infile '/home/mysql/film_test.txt' into table film_test2;
Query OK, 529056 rows affected (1 min 55.12 sec)
Records: 529056 Deleted: 0 Skipped: 0 Warnings: 0
而用 alter table tbl_name disable keys方式总耗时 6.34 + 12.25 = 18.59秒,提高了 6倍多。
mysql> alter table film_test2 disable keys;
Query OK, 0 rows affected (0.00 sec)
mysql> load data infile '/home/mysql/film_test.txt' into table film_test2;
Query OK, 529056 rows affected (6.34 sec)
Records: 529056 Deleted: 0 Skipped: 0 Warnings: 0
mysql> alter table film_test2 enable keys;
Query OK, 0 rows affected (12.25 sec)
上面是对MyISAM表进行数据导入时的优化措施,对于InnoDB类型的表,这种方式并不能提高导入数据的效率,可以有以下几种方式提高InnoDB表的导入效率。
(1)因为InnoDB类型的表是按照主键的顺序保存的,所以将导入的数据按照主键的顺序排列,可以有效地提高导入数据的效率。
例如,下面的文本 film_test3.txt 是按表 film_test4 的主键存储的,那么导入时共耗时27.92秒。
mysql> load data infile '/home/mysql/film_test3.txt' into table film_test4;
Query OK, 1587168 rows affected (22.92 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
而下面的film_test4.txt是没有任何顺序的文本,那么导入时共耗时31.16秒。
mysql> load data infile '/home/mysql/film_test4.txt' into table film_test4;
Query OK, 1587168 rows affected (31.16 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
从上面的例子可以看出,当被导入的文件按表主键顺序存储时比不按主键顺序存储时快1.12倍。
(2)在导入数据前执行SET UNIQUE_CHECKS=0,关闭唯一性校验,在导入结束后执行SET UNIQUE_CHECKS=1,恢复唯一性校验,可以提高导入的效率。
例如,当UNIQUE_CHECKS=1时:
mysql> load data infile '/home/mysql/film_test3.txt' into table film_test4;
Query OK, 1587168 rows affected (22.92 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
当SET UNIQUE_CHECKS=0时:
mysql> load data infile '/home/mysql/film_test3.txt' into table film_test4;
Query OK, 1587168 rows affected (19.92 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
可见UNIQUE_CHECKS=0时比SET UNIQUE_CHECKS=1时要快一些。
(3)如果应用使用自动提交的方式,建议在导入前执行SET AUTOCOMMIT=0,关闭自动提交,导入结束后再执行SET AUTOCOMMIT=1,打开自动提交,也可以提高导入的效率。
例如,当AUTOCOMMIT=1时:
mysql> load data infile '/home/mysql/film_test3.txt' into table film_test4;
Query OK, 1587168 rows affected (22.92 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
当AUTOCOMMIT=0时:
mysql> load data infile '/home/mysql/film_test3.txt' into table film_test4;
Query OK, 1587168 rows affected (20.87 sec)
Records: 1587168 Deleted: 0 Skipped: 0 Warnings: 0
对比一下可以知道,当AUTOCOMMIT=0时比AUTOCOMMIT=1时导入数据要快一些。