这些性能技巧补充了 第 10.2.5.1 节,“优化 INSERT 语句” 中针对快速插入的总体指南。
对于
MyISAM
表,如果数据文件中间没有删除的行,您可以使用并发插入,在SELECT
语句运行的同时添加行。参见 第 10.11.3 节,“并发插入”。通过一些额外的工作,可以使
LOAD DATA
在MyISAM
表具有多个索引时,对于该表运行得更快。使用以下过程执行
FLUSH TABLES
语句或 mysqladmin flush-tables 命令。使用 myisamchk --keys-used=0 -rq
/path/to/db/tbl_name
删除表中所有索引的使用。使用
LOAD DATA
将数据插入表中。这不会更新任何索引,因此速度非常快。如果您打算将来只从该表中读取,请使用 myisampack 对其进行压缩。参见 第 18.2.3.3 节,“压缩表特性”。
使用 myisamchk -rq
/path/to/db/tbl_name
重新创建索引。这会在将索引写入磁盘之前在内存中创建索引树,这比在LOAD DATA
期间更新索引快得多,因为它避免了大量的磁盘查找。生成的索引树也是完全平衡的。执行
FLUSH TABLES
语句或 mysqladmin flush-tables 命令。
LOAD DATA
如果您要向其中插入数据的MyISAM
表为空,则会自动执行上述优化。自动优化与显式使用该过程之间的主要区别在于,您可以让 myisamchk 为索引创建分配比您希望服务器在执行LOAD DATA
语句时为索引重新创建分配的更多的临时内存。您还可以使用以下语句而不是 myisamchk,为
MyISAM
表禁用或启用非唯一索引。如果您使用这些语句,您可以跳过FLUSH TABLES
操作ALTER TABLE tbl_name DISABLE KEYS; ALTER TABLE tbl_name ENABLE KEYS;
为了加快对非事务表执行多个语句的
INSERT
操作,请锁定您的表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
插入所有行,则不需要显式锁定语句。锁定还会降低多个连接测试的总时间,尽管各个连接的最大等待时间可能会增加,因为它们会等待锁。假设五个客户端尝试同时执行以下插入操作
连接 1 执行 1000 次插入
连接 2、3 和 4 执行 1 次插入
连接 5 执行 1000 次插入
如果您不使用锁定,连接 2、3 和 4 会在 1 和 5 之前完成。如果您使用锁定,连接 2、3 和 4 可能不会在 1 或 5 之前完成,但总时间应该快约 40%。
INSERT
、UPDATE
和DELETE
操作在 MySQL 中非常快,但您可以通过在执行超过大约 5 个连续插入或更新的操作周围添加锁来获得更好的整体性能。如果您执行了非常多的连续插入操作,则可以执行一个LOCK TABLES
,然后在一段时间后(每 1000 行左右)执行一个UNLOCK TABLES
,以允许其他线程访问表。这仍然会导致性能的显著提升。为了提高
MyISAM
表的性能,无论使用LOAD DATA
还是INSERT
,请通过增加key_buffer_size
系统变量来扩大键缓存。参见 第 7.1.1 节,“配置服务器”。