8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

MySQL 8.4 参考手册 / 10 优化 / 10.6 MyISAM 表的优化 / 10.6.2 MyISAM 表的批量数据加载
中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

10.6.2 MyISAM 表的大批量数据加载10.6.2 Bulk Data Loading for MyISAM Tables

这些性能提示补充了第 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 a MyISAM table, you can use concurrent inserts to add rows at the same time that SELECT statements 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 make LOAD DATA run even faster for a MyISAM table when the table has many indexes. Use the following procedure:

    1. 执行一个 FLUSH TABLES 语句或一个 mysqladmin flush-tables 命令。Execute a FLUSH TABLES statement or a mysqladmin flush-tables command.

    2. 使用 myisamchk --keys-used=0 -rq /path/to/db/tbl_name 来移除表的所有索引使用。Use myisamchk --keys-used=0 -rq /path/to/db/tbl_name to remove all use of indexes for the table.

    3. 使用 LOAD DATA 向表中插入数据。这不会更新任何索引,因此速度非常快。Insert data into the table with LOAD DATA. This does not update any indexes and therefore is very fast.

    4. 如果您将来只打算从表中读取数据,请使用 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”.

    5. 使用 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 during LOAD DATA because it avoids lots of disk seeks. The resulting index tree is also perfectly balanced.

    6. 执行一个 FLUSH TABLES 语句或一个 mysqladmin flush-tables 命令。Execute a FLUSH TABLES statement or a mysqladmin flush-tables command.

    LOAD DATA 会在插入数据的 MyISAM 表为空时自动执行前述优化。自动优化与显式使用该过程的主要区别在于,你可以让 myisamchk 为索引创建分配比服务器在执行 LOAD DATA 语句时索引重建可能分配的更多的临时内存。LOAD DATA performs the preceding optimization automatically if the MyISAM table 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 the LOAD DATA statement.

    您也可以使用以下语句来禁用或启用 MyISAM 表的非唯一索引,而不是使用 myisamchk。如果使用这些语句,您可以跳过 FLUSH TABLES 操作:You can also disable or enable the nonunique indexes for a MyISAM table by using the following statements rather than myisamchk. If you use these statements, you can skip the FLUSH TABLES operations:

    ALTER TABLE tbl_name DISABLE KEYS;
    ALTER TABLE tbl_name ENABLE KEYS;
    
  • 为了加快对非事务表执行多条语句的 INSERT 操作,请锁定您的表:To speed up INSERT operations 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 all INSERT statements have completed. Normally, there would be as many index buffer flushes as there are INSERT statements. Explicit locking statements are not needed if you can insert all rows with a single INSERT.

    锁定也会减少多连接测试的总时间,尽管单个连接的最大等待时间可能会增加,因为它们需要等待锁。假设有五个客户端尝试同时进行插入操作,如下所示: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, and DELETE operations 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 a LOCK TABLES followed by an UNLOCK TABLES once 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 慢得多,即使使用了刚才概述的策略。INSERT is still much slower for loading data than LOAD DATA, even when using the strategies just outlined.

  • 为了提高 MyISAM 表的性能,无论是对于 LOAD DATA 还是 INSERT,可以通过增加 key_buffer_size 系统变量来扩大键缓冲区。参见 第 7.1.1 节,“配置服务器”。To increase performance for MyISAM tables, for both LOAD DATA and INSERT, enlarge the key cache by increasing the key_buffer_size system variable. See Section 7.1.1, “Configuring the Server”.