8.6.2 MyISAMtable 的批量数据加载
这些性能提示补充了有关在第 8.2.4.1 节“优化 INSERT 语句”中快速插入的一般准则。
-
对于
MyISAM
table,如果数据文件中间没有删除的行,则可以使用并发插入在SELECT语句运行的同时添加行。参见第 8.11.3 节“并发插入”。 -
通过一些额外的工作,当 table 具有许多索引时,可以使LOAD DATA在
MyISAM
table 中运行得更快。使用以下过程: -
使用myisamchk --keys-used = 0 -rq/path/to/db/tbl_name删除 table 的所有索引使用。
-
使用LOAD DATA将数据插入 table 中。这不会更新任何索引,因此非常快。
-
如果将来只打算从 table 中读取,请使用myisampack对其进行压缩。参见第 15.2.3.3 节“压缩 tableFeature”。
-
用myisamchk -rq/path/to/db/tbl_name重新创建索引。这将在将索引树写入磁盘之前在内存中创建索引树,这比在LOAD DATA期间更新索引要快得多,因为它避免了很多磁盘查找。生成的索引树也完美平衡。
如果要向其中插入数据的MyISAM
table 为空,则LOAD DATA自动执行上述优化。自动优化和显式使用该过程之间的主要区别在于,与让服务器执行LOAD DATA语句时为索引重新创建分配的空间相比,您可以让myisamchk为索引创建分配的临时内存要多得多。
您还可以通过使用以下语句而不是myisamchk来禁用或启用MyISAM
table 的非唯一索引。如果使用这些语句,则可以跳过FLUSH TABLES操作:
ALTER TABLE tbl_name DISABLE KEYS;
ALTER TABLE tbl_name ENABLE KEYS;
- 要加快对非事务性 table 使用多条语句执行的INSERT操作,请锁定 table:
LOCK TABLES a WRITE;
INSERT INTO a VALUES (1,23),(2,34),(4,33);
INSERT INTO a VALUES (8,26),(6,29);
...
UNLOCK TABLES;
这将提高性能,因为在所有INSERT语句完成之后,索引缓冲区仅刷新一次到磁盘。通常,索引缓冲区刷新与INSERT语句一样多。如果可以用单个INSERT插入所有行,则不需要显式的锁定语句。
锁定还减少了多连接测试的总时间,尽管单个连接的最大 await 时间可能会增加,因为它们会 await 锁定。假设五个 Client 端尝试同时执行插入,如下所示:
-
连接 1 可插入 1000 次
-
连接 2、3 和 4 做 1 插入
-
连接 5 可插入 1000 次
-
如果不使用锁定,则连接 2、3 和 4 会在 1 和 5 之前完成。如果使用锁定,则连接 2、3 和 4 可能不会在 1 或 5 之前完成,但是总时间应为 40%快点。
INSERT,UPDATE和DELETE操作在 MySQL 中非常快,但是您可以通过在执行大约五个以上的连续插入或更新的所有操作周围添加锁来获得更好的整体性能。如果您执行许多连续的插入操作,则可以不时进行一次LOCK TABLES后跟UNLOCK TABLES(每行 1,000 行左右)以允许其他线程访问 table。这仍然会带来不错的性能提升。
即使使用刚刚概述的策略,INSERT加载数据的速度仍然比LOAD DATA慢得多。
- 要提高
MyISAM
table 的性能,对于LOAD DATA和INSERT,请通过增加key_buffer_size系统变量来扩大键高速缓存。参见第 5.1.1 节“配置服务器”。