**NOT** 在 MySQL 中使用 MEMORY 存储引擎的原因是什么?

Mic*_*wan 33 mysql storage-engine memory

我最近发现 MySQL 有一个我不知道的“内存”引擎(我的大部分数据库工作都是针对业余项目的,所以我边走边学习我需要的东西)。似乎这个选项应该让我大大提高性能,所以我想知道它是否有任何缺点。我所知道的两个是:

  1. 我需要有足够的内存来保存有问题的表。
  2. 如果机器关闭,这些表就会丢失。

我相信 #1 不应该是一个问题,因为我使用的是 AWS EC2,并且可以根据需要移动到具有更多内存的实例类型。我相信我可以通过根据需要转储回磁盘来缓解 #2。

还有哪些问题?内存引擎能否提供比 MyISAM 或 InnoDB 更差的性能?我想我读过一些关于这个引擎的索引不同的东西;这是我需要担心的事情吗?

Dav*_*ett 27

查看http://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html上的功能可用性列表,两个可能的问题会跳出来:

  1. 没有事务或 FK 支持,这意味着你必须在你自己的代码中管理事务完整性和参照完整性(这可能比让数据库为你做这件事效率低得多,尽管这在很大程度上取决于你的应用程序的预期的行为模式)。
  2. 仅表级锁定:如果您的应用程序需要多个并发写入器到同一组表,或者在您的读取操作使用锁来确保读取一致数据的情况下,这可能是可扩展性的重大障碍 - 在这种情况下,基于磁盘的表如果当前有足够的内容缓存在 RAM 中,则支持更精细的锁粒度会表现得更好。

除此之外,假设您有足够的 RAM,基于内存的表应该比基于磁盘的表快。显然,您需要考虑将快照写入磁盘以解决重置服务器实例时发生的问题,如果数据需要经常捕获(如果您可以忍受失去一天的时间),这可能会完全抵消整体性能优势在这种情况下,您可以每天只备份一次数据,但在大多数情况下这是不可接受的)。

另一种方法可能是:

  1. 使用基于磁盘的表,但请确保您有足够的 RAM 以在任何给定时间将它们全部保存在 RAM 中(并且“足够的 RAM”可能比您想象的要多,因为您需要考虑机器、操作系统上的任何其他进程IO 缓冲区/缓存等)
  2. 在每次启动时扫描表的全部内容(所有数据和索引页)以将内容预加载到内存中,SELECT * FROM <table> ORDER BY <pkey fields>依次为每个表和SELECT <indexed fields> FROM <table> ORDER BY <index fields>每个索引

这样您的所有数据都在 RAM 中,您只需担心写入操作的 I/O 性能。如果您的应用程序的公共工作集比整个数据库小得多(通常情况下是这样 - 在大多数应用程序中,大多数用户只会查看最新的数据),您最好对多少有更多的选择性您扫描以预加载到内存中,从而允许根据需要从磁盘加载其余部分。


Mor*_*ker 14

有很多情况不使用内存存储引擎 - 并且 InnoDB 会更快。您只需要考虑并发性而不是琐碎的单线程测试。

如果您有足够大的缓冲池,那么 InnoDB 也将完全驻留在内存中以进行读取操作。数据库有缓存。他们让自己暖和起来!

另外 - 不要低估行级锁定和MVCC的价值(读者不会阻止作者)。当写入必须持续到磁盘时,它可能会“更慢”。但至少在写入操作期间您不会像在内存表上那样阻塞(没有 MVCC;表级锁定)。