### 8.6.1 优化 MyISAM 查询

一些加快查询速度的一般技巧`MyISAM`表：

-   为了帮助 MySQL 更好地优化查询，使用[`分析表`](analyze-table.html)或运行[**myisamchk——分析**](myisamchk.html)加载数据后的表上。这会更新每个索引部分的值，该值指示具有相同值的平均行数。（对于唯一索引，这始终是 1。）当您基于非常数表达式连接两个表时，MySQL 使用它来决定选择哪个索引。您可以使用以下方法检查表分析的结果`显示索引 *`tbl_name`*`并检查`基数`价值。[**myisamchk --description --verbose**](myisamchk.html)显示索引分布信息。

-   要根据索引对索引和数据进行排序，请使用[**myisamchk --sort-index --sort-records=1**](myisamchk.html)（假设您要对索引 1 进行排序）。如果您有一个唯一索引，您希望根据该索引按顺序读取所有行，那么这是一种加快查询速度的好方法。第一次以这种方式对大表进行排序时，可能需要很长时间。

-   尽量避免复杂[`选择`](select.html)查询`MyISAM`经常更新的表，以避免由于读取器和写入器之间的争用而发生的表锁定问题。

-   `MyISAM`支持并发插入：如果一个表在数据文件中间没有空闲块，你可以[`插入`](insert.html)在其他线程从表中读取的同时将新行写入其中。如果能够做到这一点很重要，请考虑以避免删除行的方式使用该表。另一种可能性是运行[`优化表`](optimize-table.html)从表中删除大量行后对表进行碎片整理。这种行为是通过设置[`并发插入`](server-system-variables.html#sysvar_concurrent_insert)多变的。您可以强制追加新行（因此允许并发插入），即使在已删除行的表中也是如此。看[第 8.11.3 节，“并发插入”](concurrent-inserts.html).

-   为了`MyISAM`经常更改的表，尽量避免所有可变长度列（[`VARCHAR`](char.html),[`斑点`](blob.html)， 和[`文本`](blob.html)）。如果该表甚至包含单个可变长度列，则该表使用动态行格式。看[第 16 章，*替代存储引擎*](storage-engines.html).

-   仅仅因为行变大而将表拆分为不同的表通常是没有用的。在访问一行时，最大的性能损失是查找行的第一个字节所需的磁盘寻道。找到数据后，大多数现代磁盘可以以足够快的速度读取整个行，以供大多数应用程序使用。拆分表产生显着差异的唯一情况是，如果它是`MyISAM`使用动态行格式的表格，您可以将其更改为固定的行大小，或者如果您经常需要扫描表格但不需要大部分列。看[第 16 章，*替代存储引擎*](storage-engines.html).

-   采用`更改表 ... 按 * 排序`expr1`*, *`expr2`*, ...`如果您通常在`*`expr1`*, *`expr2`*, ...`命令。通过在对表进行大量更改后使用此选项，您可以获得更高的性能。

-   如果您经常需要根据大量行的信息计算计数等结果，则最好引入一个新表并实时更新计数器。以下表格的更新非常快：

    ```
    UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;
    ```

    这在您使用 MySQL 存储引擎时非常重要，例如`MyISAM`仅具有表级锁定（具有单个写入器的多个读取器）。这也为大多数数据库系统提供了更好的性能，因为在这种情况下，行锁定管理器的工作较少。

-   采用[`优化表`](optimize-table.html)定期避免动态格式的碎片`MyISAM`表。看[第 16.2.3 节，“MyISAM 表存储格式”](myisam-table-formats.html).

-   声明一个`MyISAM`表与`DELAY_KEY_WRITE=1`table 选项使索引更新更快，因为它们在表关闭之前不会刷新到磁盘。不利的一面是，如果在这样的表打开时有什么东西杀死了服务器，你必须通过运行服务器来确保表是正常的[`myisam_recover_options`](server-system-variables.html#sysvar_myisam_recover_options)系统变量集，或通过运行[**迈萨姆奇克**](myisamchk.html)在重新启动服务器之前。（但是，即使在这种情况下，您也不应该因为使用`DELAY_KEY_WRITE`，因为关键信息总是可以从数据行中生成的。）

-   字符串会自动压缩前缀和结束空间`MyISAM`索引。看[第 13.1.15 节，“CREATE INDEX 语句”](create-index.html).

-   您可以通过在应用程序中缓存查询或答案，然后一起执行许多插入或更新来提高性能。在此操作期间锁定表可确保索引缓存在所有更新后仅刷新一次。
