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