RAMdisk 上的 MySQL 内存引擎与 InnoDB

Kav*_*gel 5 mysql memory performance innodb ramdisk

我正在编写一些软件,需要将数据从分层类型的格式扁平化为表格格式。与其每次都用一种编程语言完成并提供它,我想将结果缓存几秒钟,然后使用 SQL 进行排序和过滤。在使用时,我们说的是在这几秒钟的过程中进行了 400,000 次写入和 1 次或 2 次读取。

每个表将包含 3 到 15 列。每行将包含 100 字节到 2,000 字节的数据,尽管在某些情况下,某些行可能会达到 15,000 字节。如有必要,我可以剪辑数据以保持理智。

我正在考虑的主要选择是:

MySQL的内存引擎

一个不错的选择,几乎是专门为我的用例编写的!但是……“MEMORY 表使用固定长度的行存储格式。可变长度类型(如 VARCHAR)使用固定长度存储。MEMORY 表不能包含 BLOB 或 TEXT 列。” - 不幸的是,我确实有长度可达 10,000 个字符的文本字段 - 即使是这个数字也没有特别限制。我可以在循环扁平化时根据文本列的最大长度调整 varchar 长度,但这并不完全优雅。另外,对于我偶尔的 15,000 个字符行,这是否意味着我需要为数据库中的每一行分配 15,000 个字符?如果有 100,000 行,那就是 1.3 GB,不包括开销!

RAMDisk 上的 InnoDB

这是为了在云上运行,我可以轻松地启动具有 16GB 内存的服务器,配置 MySQL 以写入 tmpfs 并使用全功能的 MySQL。我对此的担忧是空间。虽然我确信工程师已经编写了内存引擎来防止消耗所有临时存储和服务器崩溃,但我怀疑这个解决方案是否知道何时停止。在数据库格式下,我的 2,000 字节数据将消耗多少实际空间?我怎样才能监控它?

奖金问题

索引 实际上我会提前知道哪些列需要过滤和排序。我可以在插入之前设置索引,但是老实说,我可以期望在 ram 磁盘上获得什么样的性能提升?索引增加了多少额外开销?

插入 我假设用一个查询插入多行会更快。但是一个查询或一系列大型查询存储在内存中,并且我们正在写入内存,因此如果我这样做,我暂时需要双倍内存。那么我们谈论一次做一两个或一百个,并且必须等待它完成才能处理更多.. InnoDB 不锁定表,但我担心发送两个查询彼此太近而混淆MySQL。这是一个有效的担忧吗?由于表锁定,使用 MEMORY 引擎我肯定必须等待完成。

临时 临时表除了在数据库连接关闭时被删除之外还有什么好处吗?

O. *_*nes 2

我建议你使用MyISAM。使用适合您的查询的索引创建表。然后禁用键、加载表并启用键。

我建议您为您的系统制定这样的规则。我曾经非常有效地使用过类似的规则。

保留该表的两份副本。呼叫第一个table_active和第二个table_loading

当需要加载数据的新副本时,请使用如下命令。

  ALTER TABLE table_loading DISABLE KEYS;
  /* do your insertions here, to table_loading */
  /* consider using LOAD DATA INFILE if it makes sense.  */
  ALTER TABLE table_loading ENABLE KEYS;  /* this will take a while */
  /* at this point, suspend your software that's reading table_active */
  RENAME TABLE table_active TO table_old;
  RENAME TABLE table_loading TO table_active;
  /* now you can resume running your software */
  TRUNCATE TABLE table_old;
  RENAME TABLE table_old TO table_loading;
Run Code Online (Sandbox Code Playgroud)

或者,您可以DROP TABLE table_old;创建一个新表来table_loading代替上次重命名。

这种双表(双缓冲)策略应该工作得很好。它会产生一些延迟,因为读取表的软件将在旧副本上运行。但您将避免从未完全加载的表中读取数据。

我建议使用 MyISAM,因为您不会耗尽 RAM 并崩溃,并且不会有固定行长度开销或事务开销。但您也可以考虑 MariaDB 和 Aria 存储引擎,它们在利用 RAM 缓冲区方面做得很好。

如果您确实使用 MEMORY 存储引擎,请务必调整您的max_heap_table_size系统变量。如果您的读取查询将使用索引范围扫描(顺序索引访问),请务必指定 BTREE 样式索引。请参阅此处:http ://dev.mysql.com/doc/refman/5.1/en/memory-storage-engine.html