我目前正在对 MyISAM 表运行一些密集的 SELECT 查询。该表大约有 100 MiB(800,000 行)并且它永远不会改变。
我需要提高脚本的性能,所以我正在考虑将表从 MyISAM 移动到 MEMORY 存储引擎,这样我就可以将它完全加载到内存中。
除了 MEMORY 存储引擎,我还有哪些选项可以将 100 MiB 的表加载到内存中?
我目前正在对 MyISAM 表运行一些密集的 SELECT 查询。该表大约有 100 MiB(800,000 行)并且它永远不会改变。
我需要提高脚本的性能,所以我正在考虑将表从 MyISAM 移动到 MEMORY 存储引擎,这样我就可以将它完全加载到内存中。
除了 MEMORY 存储引擎,我还有哪些选项可以将 100 MiB 的表加载到内存中?
无论您使用什么存储引擎,一个有 800k 行的表对 mysql 来说都不是问题。大小为 100 MB 的完整表(数据和键)应该存在于内存中(mysql 键缓存、OS 文件缓存或两者兼有)。
首先,您检查索引。在大多数情况下,优化索引会给您带来最佳的性能提升。永远不要做任何其他事情,除非你很确定它们的形状。使用 调用查询EXPLAIN
并注意未使用索引或使用错误索引的情况。这应该使用真实世界的数据而不是在具有测试数据的服务器上完成。
优化索引后,查询应在几分之一秒内完成。如果查询仍然太慢,那么只需尝试通过在应用程序中使用缓存(memcached 等)来避免运行它们。鉴于表中的数据永远不会改变,旧的缓存数据等应该没有任何问题。
假设数据很少更改,您可能会使用MySql 查询缓存显着提高查询的性能。
如果您的表被大量查询,它可能已经在操作系统级别缓存,具体取决于您的服务器中有多少内存。
MyISAM 还允许使用称为MyISAM Key Cache的机制将 MyISAM 表索引预加载到内存中。创建键缓存后,您可以使用CACHE INDEX或LOAD INDEX语法将索引加载到缓存中。
我假设您已经分析了您的表和查询并在实际查询之后优化了您的索引?否则,在尝试将整个表存储在内存中之前,这确实是您应该做的事情。
如果您有足够的内存分配给 Mysql 使用 - 在 Innodb 缓冲池中,或供 MyIsam 使用,您可以将数据库读入内存(只是一个 'SELECT * from tablename'),如果没有理由删除它,它会保留那里。
您还可以获得更好的密钥使用,因为 MEMORY 表只使用哈希键,而不是完整的 btree 访问,对于较小的、非唯一的键可能足够胖,或者对于这么大的表来说就不够了。
像往常一样,最好的做法是对其进行基准测试。
另一个想法是,如果您使用的是 v5.1,则使用 ARCHIVE 表类型,它可以被压缩,并且还可以加快对内容的访问速度,如果它们易于压缩的话。这会交换 CPU 时间来解压缩以进行 IO/内存访问。
如果数据从不改变,您可以轻松地将表复制到多个数据库服务器上。
这样,您可以将一些查询卸载到不同的服务器,为主服务器获得一些额外的喘息空间。
速度提升取决于当前的数据库负载,如果您的数据库负载非常低,则不会有任何提升。
PS:
您知道,当数据库重新启动时,MEMORY 表会忘记它们的内容!