这些性能提示补充了第 10.2.5.1 节“优化 INSERT”中快速插入的一般准则语句”。These performance tips supplement the general guidelines for fast inserts in Section 10.2.5.1, “Optimizing INSERT Statements”.
对于
MyISAM表,如果数据文件中间没有被删除的行,你可以使用并发插入在SELECT语句运行的同时添加行。参见 第 10.11.3 节,“并发插入”。For aMyISAMtable, you can use concurrent inserts to add rows at the same time thatSELECTstatements are running, if there are no deleted rows in middle of the data file. See Section 10.11.3, “Concurrent Inserts”.通过一些额外操作,当
MyISAM表拥有许多索引时,LOAD DATA可以运行得更快。使用以下步骤:With some extra work, it is possible to makeLOAD DATArun even faster for aMyISAMtable when the table has many indexes. Use the following procedure:执行一个
FLUSH TABLES语句或一个 mysqladmin flush-tables 命令。Execute aFLUSH TABLESstatement or a mysqladmin flush-tables command.使用 myisamchk --keys-used=0 -rq
/path/to/db/tbl_name来移除表的所有索引使用。Use myisamchk --keys-used=0 -rq/path/to/db/tbl_nameto remove all use of indexes for the table.使用
LOAD DATA向表中插入数据。这不会更新任何索引,因此速度非常快。Insert data into the table withLOAD DATA. This does not update any indexes and therefore is very fast.如果您将来只打算从表中读取数据,请使用 myisampack 对其进行压缩。请参见 第 18.2.3.3 节,“压缩表的特性”。If you intend only to read from the table in the future, use myisampack to compress it. See Section 18.2.3.3, “Compressed Table Characteristics”.
使用 myisamchk -rq
/path/to/db/tbl_name重新创建索引。这会在将索引写入磁盘之前先在内存中创建索引树,这比在LOAD DATA期间更新索引要快得多,因为它避免了大量的磁盘寻址。生成的索引树也是完全平衡的。Re-create the indexes with myisamchk -rq/path/to/db/tbl_name. This creates the index tree in memory before writing it to disk, which is much faster than updating the index duringLOAD DATAbecause it avoids lots of disk seeks. The resulting index tree is also perfectly balanced.执行一个
FLUSH TABLES语句或一个 mysqladmin flush-tables 命令。Execute aFLUSH TABLESstatement or a mysqladmin flush-tables command.
LOAD DATA会在插入数据的MyISAM表为空时自动执行前述优化。自动优化与显式使用该过程的主要区别在于,你可以让 myisamchk 为索引创建分配比服务器在执行LOAD DATA语句时索引重建可能分配的更多的临时内存。LOAD DATAperforms the preceding optimization automatically if theMyISAMtable into which you insert data is empty. The main difference between automatic optimization and using the procedure explicitly is that you can let myisamchk allocate much more temporary memory for the index creation than you might want the server to allocate for index re-creation when it executes theLOAD DATAstatement.您也可以使用以下语句来禁用或启用
MyISAM表的非唯一索引,而不是使用 myisamchk。如果使用这些语句,您可以跳过FLUSH TABLES操作:You can also disable or enable the nonunique indexes for aMyISAMtable by using the following statements rather than myisamchk. If you use these statements, you can skip theFLUSH TABLESoperations:ALTER TABLE
tbl_nameDISABLE KEYS; ALTER TABLEtbl_nameENABLE KEYS;为了加快对非事务表执行多条语句的
INSERT操作,请锁定您的表:To speed upINSERToperations that are performed with multiple statements for nontransactional tables, lock your tables: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插入所有行,则不需要显式锁定语句。This benefits performance because the index buffer is flushed to disk only once, after allINSERTstatements have completed. Normally, there would be as many index buffer flushes as there areINSERTstatements. Explicit locking statements are not needed if you can insert all rows with a singleINSERT.锁定也会减少多连接测试的总时间,尽管单个连接的最大等待时间可能会增加,因为它们需要等待锁。假设有五个客户端尝试同时进行插入操作,如下所示:Locking also lowers the total time for multiple-connection tests, although the maximum wait time for individual connections might go up because they wait for locks. Suppose that five clients attempt to perform inserts simultaneously as follows:
连接 1 执行 1000 次插入Connection 1 does 1000 inserts
连接 2、3 和 4 各执行 1 次插入Connections 2, 3, and 4 do 1 insert
连接 5 执行 1000 次插入Connection 5 does 1000 inserts
如果不使用锁,连接 2、3 和 4 会在 1 和 5 之前完成。如果使用锁,连接 2、3 和 4 可能不会在 1 或 5 之前完成,但总时间大约会快 40%。If you do not use locking, connections 2, 3, and 4 finish before 1 and 5. If you use locking, connections 2, 3, and 4 probably do not finish before 1 or 5, but the total time should be about 40% faster.
INSERT、UPDATE和DELETE操作在 MySQL 中非常快,但如果对超过大约五次连续插入或更新的操作周围加锁,您可以获得更好的整体性能。如果您进行非常多的连续插入,可以偶尔(大约每 1,000 行)执行一次LOCK TABLES,然后再执行UNLOCK TABLES,以允许其他线程访问表。这仍然会带来不错的性能提升。INSERT,UPDATE, andDELETEoperations are very fast in MySQL, but you can obtain better overall performance by adding locks around everything that does more than about five successive inserts or updates. If you do very many successive inserts, you could do aLOCK TABLESfollowed by anUNLOCK TABLESonce in a while (each 1,000 rows or so) to permit other threads to access table. This would still result in a nice performance gain.INSERT在加载数据时仍然比LOAD DATA慢得多,即使使用了刚才概述的策略。INSERTis still much slower for loading data thanLOAD DATA, even when using the strategies just outlined.为了提高
MyISAM表的性能,无论是对于LOAD DATA还是INSERT,可以通过增加key_buffer_size系统变量来扩大键缓冲区。参见 第 7.1.1 节,“配置服务器”。To increase performance forMyISAMtables, for bothLOAD DATAandINSERT, enlarge the key cache by increasing thekey_buffer_sizesystem variable. See Section 7.1.1, “Configuring the Server”.