AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 1811
Accepted
Michael McGowan
Michael McGowan
Asked: 2011-03-20 22:27:29 +0800 CST2011-03-20 22:27:29 +0800 CST 2011-03-20 22:27:29 +0800 CST

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

  • 772

我最近发现 MySQL 有一个我不知道的“内存”引擎(我的大部分数据库工作都是针对业余项目,所以我会边走边学)。看起来这个选项应该会给我带来极大的性能提升,所以我想知道它是否有任何缺点。我知道的两个是:

  1. 我需要有足够的 RAM 来保存有问题的表。
  2. 如果机器关闭,表格将丢失。

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

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

mysql storage-engine
  • 7 7 个回答
  • 50298 Views

7 个回答

  • Voted
  1. Best Answer
    David Spillett
    2011-03-21T04:30:28+08:002011-03-21T04:30:28+08:00

    查看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 性能。如果您的应用程序的通用工作集比整个数据库小得多(通常是这种情况 - 在大多数应用程序中,大多数用户只会在最长时间内查看最新数据),您可能会更好地选择多少您扫描预加载到内存中,允许按需从磁盘加载其余部分。

    • 28
  2. Morgan Tocker
    2011-03-22T13:11:04+08:002011-03-22T13:11:04+08:00

    有很多情况下不使用内存存储引擎——而 InnoDB 什么时候会更快。您只需要考虑并发性,而不是简单的单线程测试。

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

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

    • 15
  3. magallanes
    2014-06-03T13:26:09+08:002014-06-03T13:26:09+08:00

    作为记录。我在内存中测试了 Mysql 表以存储一些信息。我测试了 PHP 的 APC (APCu) 以存储相同的信息。

    对于 58000 个注册表。(varchar + 整数 + 日期)。

    1. 文本格式(csv 格式)的原始信息 24mb。
    2. PHP 的 APC 使用 44.7mb 的 RAM。
    3. Mysql 的表使用 575mb 的 RAM。

    该表只有一个索引,所以我不认为它是主要因素。

    结论:

    内存表不是“大”表的选项,因为它使用了太多内存。

    • 4
  4. Kondybas
    2018-07-08T00:59:42+08:002018-07-08T00:59:42+08:00

    基于 MEMORY 的表的另一个缺点是它们不能在同一个查询中被多次引用。至少在 v5.4 之前发现了这种行为。如何使用 CTE(自 v8.x 起)无需为复杂的过程使用基于 mem 的中间表。

    • 2
  5. user2134886
    2016-12-27T01:14:48+08:002016-12-27T01:14:48+08:00

    根据 MySQL 和 MariaDB 手册,MEMORY 存储不支持 BLOB 和 CLOB(各种 TEXT 类型)。出于我们自己的目的,这使得 MEMORY 存储引擎几乎毫无用处。

    http://dev.mysql.com/doc/refman/5.7/en/memory-storage-engine.html

    MEMORY 表不能包含 BLOB 或 TEXT 列。

    https://mariadb.com/kb/en/mariadb/memory-storage-engine/

    可变长度类型(如 VARCHAR)可用于 MEMORY 表。MEMORY 表不支持 BLOB 或 TEXT 列。

    在尝试仅将部分数据库转换为 MEMORY 存储时,我发现不支持跨存储引擎外键。因此,所有应该具有对表的外键引用的表,包含 BLOB/CLOB 也应该是非内存存储类型(至少,这会影响 InnoDB 子表)。

    • 1
  6. mopsyd
    2018-07-07T11:30:02+08:002018-07-07T11:30:02+08:00

    MEMORY 表不适用于持久存储,尤其是大型数据子集或保留至关重要的任何内容。根据我的经验,它们的最佳目的是在复杂过程期间在临时表的创建和填充期间保存临时记录,如果您将引擎的关键缓冲区阈值设置得足够高而不会产生磁盘写入。为此目的,这可以比 MyISAM 或 InnoDB 快一个数量级,因为没有磁盘 I/O,并且对于封装在特定过程中的表,索引和关系并不像它们那么重要将在预期持久性的地方。

    • 1
  7. Eljuan
    2018-10-01T14:24:12+08:002018-10-01T14:24:12+08:00

    除了前面的答案。直接来自 MySQL 5.7 手册:

    “内存性能受到单线程执行和处理更新时表锁开销导致的争用的限制。这限制了负载增加时的可伸缩性,特别是对于包含写入的语句混合。”

    ...这是一个非常现实的限制。例如:当您有多个会话试图创建良好的快速 MEMORY 临时表时,单线程可能会导致严重的性能瓶颈。

    • 1

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve