文档首页
MySQL 9.0 参考手册
相关文档 下载此手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  MyISAM 表的批量数据加载

10.6.2 MyISAM 表的批量数据加载

这些性能技巧是对 第 10.2.5.1 节,“优化 INSERT 语句” 中关于快速插入的一般指南的补充。

  • 对于 MyISAM 表,如果数据文件中间没有删除的行,您可以使用并发插入在执行 SELECT 语句的同时添加行。参见 第 10.11.3 节,“并发插入”

  • 通过一些额外的操作,当表具有多个索引时,可以使 LOAD DATAMyISAM 表的运行速度更快。使用以下步骤

    1. 执行 FLUSH TABLES 语句或 mysqladmin flush-tables 命令。

    2. 使用 myisamchk --keys-used=0 -rq /path/to/db/tbl_name 从表中删除所有索引的使用。

    3. 使用 LOAD DATA 将数据插入表中。这不会更新任何索引,因此速度非常快。

    4. 如果您打算将来只从表中读取数据,请使用 myisampack 对其进行压缩。参见 第 18.2.3.3 节,“压缩表特征”

    5. 使用 myisamchk -rq /path/to/db/tbl_name 重新创建索引。这将在将索引写入磁盘之前在内存中创建索引树,这比在执行 LOAD DATA 期间更新索引要快得多,因为它避免了许多磁盘查找。生成的索引树也是完全平衡的。

    6. 执行 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%。

    INSERTUPDATEDELETE 操作在 MySQL 中非常快,但可以通过在执行超过大约五个连续插入或更新的操作时添加锁来获得更好的整体性能。如果您执行非常多次连续插入,您可以执行 LOCK TABLES,然后偶尔(大约每 1000 行一次)执行 UNLOCK TABLES 以允许其他线程访问表。这仍然会带来不错的性能提升。

    即使使用上面概述的策略,INSERT 用于加载数据的速度仍然远低于 LOAD DATA

  • 要提高 MyISAM 表的性能,对于 LOAD DATAINSERT,请通过增加 key_buffer_size 系统变量来扩大键缓存。请参阅 第 7.1.1 节“配置服务器”