MyISAM存储引擎在以读为主的数据或低并发操作中表现最好,因为表锁限制了同时执行更新的能力。在MySQL中,InnoDB是默认的存储引擎,而不是MyISAM。
优化MyISAM查询
一些加快MyISAM表查询的一般技巧 :
为了帮助MySQL更好地优化查询,可以使用ANALYZE TABLE或运行--analyze 在加载了数据的表上进行分析。这将更新每个索引部分的值,该值指示具有相同值的平均行数。(对于唯一索引,始终为1。)MySQL使用此选项来决定在基于非常量表达式连接两个表时选择哪个索引。通过使用SHOW INDEX from tbl_name并检查基数值,可以检查表分析的结果。myisamchk--description--verbose显示索引分布信息。
要根据索引对索引和数据进行排序,请使用 myisamchk --sort-index --sort-records = 1 (假设您要对索引1进行排序)。如果您有一个唯一的索引,要根据该索引按顺序读取所有行,这是使查询更快的一种好方法。第一次以这种方式对大表进行排序可能会花费很长时间。
尝试避免SELECT 对MyISAM频繁更新的表进行复杂的查询,以避免由于读取器和写入器之间的争用而发生的表锁定问题。
MyISAM支持并发插入:如果表在数据文件的中间没有空闲块,则可以INSERT在其他线程从表读取数据的同时向其中添加新行。如果能够做到这一点很重要,请考虑以避免删除行的方式使用表。另一种可能性是运行OPTIMIZE TABLE到整理表你已经删除了很多这行之后。通过设置concurrent_insert变量可以更改此行为 。您甚至可以在已删除行的表中强制添加新行(并因此允许并发插入)。请参见第8.11.3节“并发插入”。
对于MyISAM表经常变化的,尽量避免所有变长列(VARCHAR, BLOB,和 TEXT)。如果该表甚至只包含一个可变长度的列,则使用动态行格式。请参见第16章,备用存储引擎。
通常,仅由于行变大而将表拆分为不同的表是没有用的。在访问一行时,最大的性能损失是查找该行第一个字节所需的磁盘搜索。找到数据后,大多数现代磁盘可以以足够快的速度读取整个行,以适合大多数应用程序。拆分表的唯一情况是MyISAM,可以更改为固定行大小的表是使用动态行格式的 表,还是经常需要扫描表但不需要大多数列的表。请参见第16章,备用存储引擎。
通常用于按顺序检索expr1, expr2, ...行时 使用ALTER TABLE ... ORDER BYexpr1, expr2, ...。通过在对该表进行大量更改之后使用此选项,您可能可以获得更高的性能。
如果您经常需要基于大量行中的信息来计算结果(例如计数),则最好引入一个新表并实时更新计数器。以下表格的更新非常快:
UPDATE tbl_name SET count_col=count_col+1 WHERE key_col=constant;
当您使用MySQL存储引擎(例如MyISAM仅具有表级锁定(具有单个编写器的多个读取器))时,这非常重要。这也使大多数数据库系统具有更好的性能,因为在这种情况下,行锁定管理器的工作量减少了。
OPTIMIZE TABLE 定期 使用以避免动态格式MyISAM表的碎片化 。请参见 第16.2.3节“ MyISAM表存储格式”。
MyISAM使用 DELAY_KEY_WRITE=1table选项 声明表可以使索引更新更快,因为在关闭表之前,它们不会刷新到磁盘。不利的一面是,如果在打开此类表时某些东西杀死了服务器,则必须通过myisam_recover_options 设置系统变量集运行服务器,或者在重新启动服务器之前运行 myisamchk来确保该表正常 。(但是,即使在这种情况下,也不要通过使用来丢失任何内容DELAY_KEY_WRITE,因为密钥信息始终可以从数据行中生成。)
字符串会在MyISAM索引中自动压缩前缀和结尾空间。请参见 第13.1.15节“ CREATE INDEX语句”。
您可以通过在应用程序中缓存查询或答案,然后一起执行许多插入或更新操作来提高性能。在此操作期间锁定表可确保索引缓存在所有更新之后仅刷新一次。