Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  ...  /  Optimizing MyISAM Queries

10.6.1 MyISAM 查询优化

一些通用的提示,以加速在 MyISAM 表上的查询:

  • 为了帮助 MySQL 更好地优化查询,使用 ANALYZE TABLE 或在表加载数据后运行 myisamchk --analyze。这会更新每个索引部分的值,表示平均有多少行具有相同值。(对于唯一索引,这总是 1。)MySQL 使用这个来决定在基于非常量表达式连接两个表时应该选择哪个索引。你可以通过使用 SHOW INDEX FROM tbl_name 并检查 Cardinality 值来查看分析结果。 myisamchk --description --verbose 显示索引分布信息。

  • 为了按照索引排序数据和索引本身,使用 myisamchk --sort-index --sort-records=1(假设你想按照索引 1 排序)。这对于从唯一索引中读取所有行并按照索引顺序进行排序是一个好方法。第一次对一个大表进行这种排序可能会花费很长的时间。

  • 尽量避免在频繁更新的 MyISAM 表上执行复杂的 SELECT 查询,以避免由于读者和写者之间的竞争导致的问题。

  • MyISAM 支持并发插入:如果表中没有位于数据文件中间部位的空白块,你可以同时在该表上插入新行,同时其他线程正在读取表。如果这很重要,可以考虑使用表以避免删除行的方式。另一种可能性是运行 OPTIMIZE TABLE 以在删除大量行后对表进行碎片整理。这一行为可以通过设置 concurrent_insert 变量来改变。你可以强制新行被追加(并因此允许并发插入),即使在有删除行的表中。请参阅 第 10.11.3 节,“并发插入”

  • 对于频繁变化的 MyISAM 表,尽量避免使用变长列(VARCHARBLOBTEXT)。如果表中包含任何一个变长列,表将使用动态行格式。请参阅 第 18 章,《备选存储引擎》

  • 通常,不要因为行变得很大而将表分割成不同的表。访问一行的最大性能损失是找到行首字节所需的磁盘寻找时间。一旦找到数据,绝大多数现代磁盘都能快速读取整个行,这对于大多数应用程序来说足够了。只有在以下情况下将表分割会带来显著差异:如果它是一个使用动态行格式的 MyISAM 表,你可以将其更改为固定行大小,或者你非常经常需要扫描整个表但不需要大多数列。请参阅 第 18 章,《备选存储引擎》

  • 如果你通常从表中检索行,并且按照 <expr1>, <expr2>, ... 顺序检索行,可以使用 ALTER TABLE ... ORDER BY <em class="replaceable"><expr1>, <em class="replaceable"><expr2>, ...。在对表进行大量更改后使用这个选项,你可能能够获得更高的性能。

  • 如果你经常需要基于来自许多行的信息计算结果,比如计数器,可能会更喜欢引入一个新表并实时更新计数器。以下类型的更新非常快:

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

    这对于使用 MySQL 存储引擎,如 MyISAM(只有表级锁定,多个读者和单写者)时尤为重要。这也给了大多数数据库系统更好的性能,因为行锁管理器在这种情况下有更少的工作要做。

  • 定期使用OPTIMIZE TABLE来避免动态格式MyISAM表的碎片化。参见第18.2.3节,“MyISAM 表存储格式”

  • MyISAM表中声明一个带有DELAY_KEY_WRITE=1选项的表可以使索引更新更快,因为它们不会直到表关闭时才被刷新到磁盘。然而,这也意味着如果在服务器运行期间有东西杀死了这样的表,你必须确保该表是好的,可以通过设置myisam_recover_options系统变量来做到这一点,或者在重启服务器之前运行myisamchk。(然而,即使在这种情况下,使用DELAY_KEY_WRITE也不会导致任何数据丢失,因为关键信息总是可以从数据行中生成。)

  • MyISAM索引中的字符串自动进行前缀和末尾空格压缩。参见第15.1.15节,“CREATE INDEX 语句”

  • 通过在应用程序中缓存查询或答案,并然后一起执行多个插入或更新,可以提高性能。锁定表以进行此操作确保索引缓存只在所有更新完成后被刷新一次。